diff options
Diffstat (limited to 'arch/mips/mm/uasm.c')
| -rw-r--r-- | arch/mips/mm/uasm.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 1581e9852461..611d564fdcf1 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
| @@ -31,7 +31,8 @@ enum fields { | |||
| 31 | BIMM = 0x040, | 31 | BIMM = 0x040, |
| 32 | JIMM = 0x080, | 32 | JIMM = 0x080, |
| 33 | FUNC = 0x100, | 33 | FUNC = 0x100, |
| 34 | SET = 0x200 | 34 | SET = 0x200, |
| 35 | SCIMM = 0x400 | ||
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | #define OP_MASK 0x3f | 38 | #define OP_MASK 0x3f |
| @@ -52,6 +53,8 @@ enum fields { | |||
| 52 | #define FUNC_SH 0 | 53 | #define FUNC_SH 0 |
| 53 | #define SET_MASK 0x7 | 54 | #define SET_MASK 0x7 |
| 54 | #define SET_SH 0 | 55 | #define SET_SH 0 |
| 56 | #define SCIMM_MASK 0xfffff | ||
| 57 | #define SCIMM_SH 6 | ||
| 55 | 58 | ||
| 56 | enum opcode { | 59 | enum opcode { |
| 57 | insn_invalid, | 60 | insn_invalid, |
| @@ -61,10 +64,10 @@ enum opcode { | |||
| 61 | insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, | 64 | insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, |
| 62 | insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal, | 65 | insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal, |
| 63 | insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, | 66 | insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, |
| 64 | insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, | 67 | insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, |
| 65 | insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, | 68 | insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, |
| 66 | insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, | 69 | insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, |
| 67 | insn_dins | 70 | insn_dins, insn_syscall |
| 68 | }; | 71 | }; |
| 69 | 72 | ||
| 70 | struct insn { | 73 | struct insn { |
| @@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = { | |||
| 117 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 120 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 118 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | 121 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 119 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | 122 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 123 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
| 120 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 124 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
| 121 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 125 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 122 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, | 126 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, |
| @@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = { | |||
| 136 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | 140 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, |
| 137 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 141 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
| 138 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | 142 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, |
| 143 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
| 139 | { insn_invalid, 0, 0 } | 144 | { insn_invalid, 0, 0 } |
| 140 | }; | 145 | }; |
| 141 | 146 | ||
| @@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg) | |||
| 208 | return (arg >> 2) & JIMM_MASK; | 213 | return (arg >> 2) & JIMM_MASK; |
| 209 | } | 214 | } |
| 210 | 215 | ||
| 216 | static inline __cpuinit u32 build_scimm(u32 arg) | ||
| 217 | { | ||
| 218 | if (arg & ~SCIMM_MASK) | ||
| 219 | printk(KERN_WARNING "Micro-assembler field overflow\n"); | ||
| 220 | |||
| 221 | return (arg & SCIMM_MASK) << SCIMM_SH; | ||
| 222 | } | ||
| 223 | |||
| 211 | static inline __cpuinit u32 build_func(u32 arg) | 224 | static inline __cpuinit u32 build_func(u32 arg) |
| 212 | { | 225 | { |
| 213 | if (arg & ~FUNC_MASK) | 226 | if (arg & ~FUNC_MASK) |
| @@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...) | |||
| 266 | op |= build_func(va_arg(ap, u32)); | 279 | op |= build_func(va_arg(ap, u32)); |
| 267 | if (ip->fields & SET) | 280 | if (ip->fields & SET) |
| 268 | op |= build_set(va_arg(ap, u32)); | 281 | op |= build_set(va_arg(ap, u32)); |
| 282 | if (ip->fields & SCIMM) | ||
| 283 | op |= build_scimm(va_arg(ap, u32)); | ||
| 269 | va_end(ap); | 284 | va_end(ap); |
| 270 | 285 | ||
| 271 | **buf = op; | 286 | **buf = op; |
| @@ -373,6 +388,7 @@ I_u2s3u1(_lw) | |||
| 373 | I_u1u2u3(_mfc0) | 388 | I_u1u2u3(_mfc0) |
| 374 | I_u1u2u3(_mtc0) | 389 | I_u1u2u3(_mtc0) |
| 375 | I_u2u1u3(_ori) | 390 | I_u2u1u3(_ori) |
| 391 | I_u3u1u2(_or) | ||
| 376 | I_u2s3u1(_pref) | 392 | I_u2s3u1(_pref) |
| 377 | I_0(_rfe) | 393 | I_0(_rfe) |
| 378 | I_u2s3u1(_sc) | 394 | I_u2s3u1(_sc) |
| @@ -391,6 +407,7 @@ I_0(_tlbwr) | |||
| 391 | I_u3u1u2(_xor) | 407 | I_u3u1u2(_xor) |
| 392 | I_u2u1u3(_xori) | 408 | I_u2u1u3(_xori) |
| 393 | I_u2u1msbu3(_dins); | 409 | I_u2u1msbu3(_dins); |
| 410 | I_u1(_syscall); | ||
| 394 | 411 | ||
| 395 | /* Handle labels. */ | 412 | /* Handle labels. */ |
| 396 | void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) | 413 | void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) |
