diff options
Diffstat (limited to 'arch/mips/mm/uasm.c')
-rw-r--r-- | arch/mips/mm/uasm.c | 326 |
1 files changed, 78 insertions, 248 deletions
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 942ff6c2eba2..7eb5e4355d25 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
@@ -10,17 +10,9 @@ | |||
10 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer | 10 | * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer |
11 | * Copyright (C) 2005, 2007 Maciej W. Rozycki | 11 | * Copyright (C) 2005, 2007 Maciej W. Rozycki |
12 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | 12 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) |
13 | * Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved. | ||
13 | */ | 14 | */ |
14 | 15 | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/inst.h> | ||
20 | #include <asm/elf.h> | ||
21 | #include <asm/bugs.h> | ||
22 | #include <asm/uasm.h> | ||
23 | |||
24 | enum fields { | 16 | enum fields { |
25 | RS = 0x001, | 17 | RS = 0x001, |
26 | RT = 0x002, | 18 | RT = 0x002, |
@@ -37,10 +29,6 @@ enum fields { | |||
37 | 29 | ||
38 | #define OP_MASK 0x3f | 30 | #define OP_MASK 0x3f |
39 | #define OP_SH 26 | 31 | #define OP_SH 26 |
40 | #define RS_MASK 0x1f | ||
41 | #define RS_SH 21 | ||
42 | #define RT_MASK 0x1f | ||
43 | #define RT_SH 16 | ||
44 | #define RD_MASK 0x1f | 32 | #define RD_MASK 0x1f |
45 | #define RD_SH 11 | 33 | #define RD_SH 11 |
46 | #define RE_MASK 0x1f | 34 | #define RE_MASK 0x1f |
@@ -53,8 +41,6 @@ enum fields { | |||
53 | #define FUNC_SH 0 | 41 | #define FUNC_SH 0 |
54 | #define SET_MASK 0x7 | 42 | #define SET_MASK 0x7 |
55 | #define SET_SH 0 | 43 | #define SET_SH 0 |
56 | #define SCIMM_MASK 0xfffff | ||
57 | #define SCIMM_SH 6 | ||
58 | 44 | ||
59 | enum opcode { | 45 | enum opcode { |
60 | insn_invalid, | 46 | insn_invalid, |
@@ -77,85 +63,6 @@ struct insn { | |||
77 | enum fields fields; | 63 | enum fields fields; |
78 | }; | 64 | }; |
79 | 65 | ||
80 | /* This macro sets the non-variable bits of an instruction. */ | ||
81 | #define M(a, b, c, d, e, f) \ | ||
82 | ((a) << OP_SH \ | ||
83 | | (b) << RS_SH \ | ||
84 | | (c) << RT_SH \ | ||
85 | | (d) << RD_SH \ | ||
86 | | (e) << RE_SH \ | ||
87 | | (f) << FUNC_SH) | ||
88 | |||
89 | static struct insn insn_table[] __uasminitdata = { | ||
90 | { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
91 | { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, | ||
92 | { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
93 | { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, | ||
94 | { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
95 | { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
96 | { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
97 | { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
98 | { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM }, | ||
99 | { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM }, | ||
100 | { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM }, | ||
101 | { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM }, | ||
102 | { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM }, | ||
103 | { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
104 | { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
105 | { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD }, | ||
106 | { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE }, | ||
107 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | ||
108 | { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
109 | { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
110 | { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
111 | { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
112 | { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE }, | ||
113 | { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE }, | ||
114 | { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE }, | ||
115 | { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE }, | ||
116 | { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE }, | ||
117 | { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD }, | ||
118 | { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 }, | ||
119 | { insn_ext, M(spec3_op, 0, 0, 0, 0, ext_op), RS | RT | RD | RE }, | ||
120 | { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE }, | ||
121 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
122 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, | ||
123 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | ||
124 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, | ||
125 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
126 | { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD }, | ||
127 | { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
128 | { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
129 | { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM }, | ||
130 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
131 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | ||
132 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
133 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | ||
134 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
135 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
136 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
137 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, | ||
138 | { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE }, | ||
139 | { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
140 | { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
141 | { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
142 | { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE }, | ||
143 | { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE }, | ||
144 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, | ||
145 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, | ||
146 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | ||
147 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
148 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, | ||
149 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, | ||
150 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, | ||
151 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, | ||
152 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | ||
153 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | ||
154 | { insn_invalid, 0, 0 } | ||
155 | }; | ||
156 | |||
157 | #undef M | ||
158 | |||
159 | static inline __uasminit u32 build_rs(u32 arg) | 66 | static inline __uasminit u32 build_rs(u32 arg) |
160 | { | 67 | { |
161 | WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n"); | 68 | WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n"); |
@@ -199,24 +106,6 @@ static inline __uasminit u32 build_uimm(u32 arg) | |||
199 | return arg & IMM_MASK; | 106 | return arg & IMM_MASK; |
200 | } | 107 | } |
201 | 108 | ||
202 | static inline __uasminit u32 build_bimm(s32 arg) | ||
203 | { | ||
204 | WARN(arg > 0x1ffff || arg < -0x20000, | ||
205 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
206 | |||
207 | WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n"); | ||
208 | |||
209 | return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); | ||
210 | } | ||
211 | |||
212 | static inline __uasminit u32 build_jimm(u32 arg) | ||
213 | { | ||
214 | WARN(arg & ~(JIMM_MASK << 2), | ||
215 | KERN_WARNING "Micro-assembler field overflow\n"); | ||
216 | |||
217 | return (arg >> 2) & JIMM_MASK; | ||
218 | } | ||
219 | |||
220 | static inline __uasminit u32 build_scimm(u32 arg) | 109 | static inline __uasminit u32 build_scimm(u32 arg) |
221 | { | 110 | { |
222 | WARN(arg & ~SCIMM_MASK, | 111 | WARN(arg & ~SCIMM_MASK, |
@@ -239,55 +128,7 @@ static inline __uasminit u32 build_set(u32 arg) | |||
239 | return arg & SET_MASK; | 128 | return arg & SET_MASK; |
240 | } | 129 | } |
241 | 130 | ||
242 | /* | 131 | static void __uasminit build_insn(u32 **buf, enum opcode opc, ...); |
243 | * The order of opcode arguments is implicitly left to right, | ||
244 | * starting with RS and ending with FUNC or IMM. | ||
245 | */ | ||
246 | static void __uasminit build_insn(u32 **buf, enum opcode opc, ...) | ||
247 | { | ||
248 | struct insn *ip = NULL; | ||
249 | unsigned int i; | ||
250 | va_list ap; | ||
251 | u32 op; | ||
252 | |||
253 | for (i = 0; insn_table[i].opcode != insn_invalid; i++) | ||
254 | if (insn_table[i].opcode == opc) { | ||
255 | ip = &insn_table[i]; | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | if (!ip || (opc == insn_daddiu && r4k_daddiu_bug())) | ||
260 | panic("Unsupported Micro-assembler instruction %d", opc); | ||
261 | |||
262 | op = ip->match; | ||
263 | va_start(ap, opc); | ||
264 | if (ip->fields & RS) | ||
265 | op |= build_rs(va_arg(ap, u32)); | ||
266 | if (ip->fields & RT) | ||
267 | op |= build_rt(va_arg(ap, u32)); | ||
268 | if (ip->fields & RD) | ||
269 | op |= build_rd(va_arg(ap, u32)); | ||
270 | if (ip->fields & RE) | ||
271 | op |= build_re(va_arg(ap, u32)); | ||
272 | if (ip->fields & SIMM) | ||
273 | op |= build_simm(va_arg(ap, s32)); | ||
274 | if (ip->fields & UIMM) | ||
275 | op |= build_uimm(va_arg(ap, u32)); | ||
276 | if (ip->fields & BIMM) | ||
277 | op |= build_bimm(va_arg(ap, s32)); | ||
278 | if (ip->fields & JIMM) | ||
279 | op |= build_jimm(va_arg(ap, u32)); | ||
280 | if (ip->fields & FUNC) | ||
281 | op |= build_func(va_arg(ap, u32)); | ||
282 | if (ip->fields & SET) | ||
283 | op |= build_set(va_arg(ap, u32)); | ||
284 | if (ip->fields & SCIMM) | ||
285 | op |= build_scimm(va_arg(ap, u32)); | ||
286 | va_end(ap); | ||
287 | |||
288 | **buf = op; | ||
289 | (*buf)++; | ||
290 | } | ||
291 | 132 | ||
292 | #define I_u1u2u3(op) \ | 133 | #define I_u1u2u3(op) \ |
293 | Ip_u1u2u3(op) \ | 134 | Ip_u1u2u3(op) \ |
@@ -445,7 +286,7 @@ I_u3u1u2(_ldx) | |||
445 | 286 | ||
446 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | 287 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
447 | #include <asm/octeon/octeon.h> | 288 | #include <asm/octeon/octeon.h> |
448 | void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b, | 289 | void __uasminit ISAFUNC(uasm_i_pref)(u32 **buf, unsigned int a, signed int b, |
449 | unsigned int c) | 290 | unsigned int c) |
450 | { | 291 | { |
451 | if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5) | 292 | if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5) |
@@ -457,21 +298,21 @@ void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b, | |||
457 | else | 298 | else |
458 | build_insn(buf, insn_pref, c, a, b); | 299 | build_insn(buf, insn_pref, c, a, b); |
459 | } | 300 | } |
460 | UASM_EXPORT_SYMBOL(uasm_i_pref); | 301 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_i_pref)); |
461 | #else | 302 | #else |
462 | I_u2s3u1(_pref) | 303 | I_u2s3u1(_pref) |
463 | #endif | 304 | #endif |
464 | 305 | ||
465 | /* Handle labels. */ | 306 | /* Handle labels. */ |
466 | void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) | 307 | void __uasminit ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr, int lid) |
467 | { | 308 | { |
468 | (*lab)->addr = addr; | 309 | (*lab)->addr = addr; |
469 | (*lab)->lab = lid; | 310 | (*lab)->lab = lid; |
470 | (*lab)++; | 311 | (*lab)++; |
471 | } | 312 | } |
472 | UASM_EXPORT_SYMBOL(uasm_build_label); | 313 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_build_label)); |
473 | 314 | ||
474 | int __uasminit uasm_in_compat_space_p(long addr) | 315 | int __uasminit ISAFUNC(uasm_in_compat_space_p)(long addr) |
475 | { | 316 | { |
476 | /* Is this address in 32bit compat space? */ | 317 | /* Is this address in 32bit compat space? */ |
477 | #ifdef CONFIG_64BIT | 318 | #ifdef CONFIG_64BIT |
@@ -480,7 +321,7 @@ int __uasminit uasm_in_compat_space_p(long addr) | |||
480 | return 1; | 321 | return 1; |
481 | #endif | 322 | #endif |
482 | } | 323 | } |
483 | UASM_EXPORT_SYMBOL(uasm_in_compat_space_p); | 324 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_in_compat_space_p)); |
484 | 325 | ||
485 | static int __uasminit uasm_rel_highest(long val) | 326 | static int __uasminit uasm_rel_highest(long val) |
486 | { | 327 | { |
@@ -500,77 +341,66 @@ static int __uasminit uasm_rel_higher(long val) | |||
500 | #endif | 341 | #endif |
501 | } | 342 | } |
502 | 343 | ||
503 | int __uasminit uasm_rel_hi(long val) | 344 | int __uasminit ISAFUNC(uasm_rel_hi)(long val) |
504 | { | 345 | { |
505 | return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; | 346 | return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; |
506 | } | 347 | } |
507 | UASM_EXPORT_SYMBOL(uasm_rel_hi); | 348 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_rel_hi)); |
508 | 349 | ||
509 | int __uasminit uasm_rel_lo(long val) | 350 | int __uasminit ISAFUNC(uasm_rel_lo)(long val) |
510 | { | 351 | { |
511 | return ((val & 0xffff) ^ 0x8000) - 0x8000; | 352 | return ((val & 0xffff) ^ 0x8000) - 0x8000; |
512 | } | 353 | } |
513 | UASM_EXPORT_SYMBOL(uasm_rel_lo); | 354 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_rel_lo)); |
514 | 355 | ||
515 | void __uasminit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr) | 356 | void __uasminit ISAFUNC(UASM_i_LA_mostly)(u32 **buf, unsigned int rs, long addr) |
516 | { | 357 | { |
517 | if (!uasm_in_compat_space_p(addr)) { | 358 | if (!ISAFUNC(uasm_in_compat_space_p)(addr)) { |
518 | uasm_i_lui(buf, rs, uasm_rel_highest(addr)); | 359 | ISAFUNC(uasm_i_lui)(buf, rs, uasm_rel_highest(addr)); |
519 | if (uasm_rel_higher(addr)) | 360 | if (uasm_rel_higher(addr)) |
520 | uasm_i_daddiu(buf, rs, rs, uasm_rel_higher(addr)); | 361 | ISAFUNC(uasm_i_daddiu)(buf, rs, rs, uasm_rel_higher(addr)); |
521 | if (uasm_rel_hi(addr)) { | 362 | if (ISAFUNC(uasm_rel_hi(addr))) { |
522 | uasm_i_dsll(buf, rs, rs, 16); | 363 | ISAFUNC(uasm_i_dsll)(buf, rs, rs, 16); |
523 | uasm_i_daddiu(buf, rs, rs, uasm_rel_hi(addr)); | 364 | ISAFUNC(uasm_i_daddiu)(buf, rs, rs, |
524 | uasm_i_dsll(buf, rs, rs, 16); | 365 | ISAFUNC(uasm_rel_hi)(addr)); |
366 | ISAFUNC(uasm_i_dsll)(buf, rs, rs, 16); | ||
525 | } else | 367 | } else |
526 | uasm_i_dsll32(buf, rs, rs, 0); | 368 | ISAFUNC(uasm_i_dsll32)(buf, rs, rs, 0); |
527 | } else | 369 | } else |
528 | uasm_i_lui(buf, rs, uasm_rel_hi(addr)); | 370 | ISAFUNC(uasm_i_lui)(buf, rs, ISAFUNC(uasm_rel_hi(addr))); |
529 | } | 371 | } |
530 | UASM_EXPORT_SYMBOL(UASM_i_LA_mostly); | 372 | UASM_EXPORT_SYMBOL(ISAFUNC(UASM_i_LA_mostly)); |
531 | 373 | ||
532 | void __uasminit UASM_i_LA(u32 **buf, unsigned int rs, long addr) | 374 | void __uasminit ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr) |
533 | { | 375 | { |
534 | UASM_i_LA_mostly(buf, rs, addr); | 376 | ISAFUNC(UASM_i_LA_mostly)(buf, rs, addr); |
535 | if (uasm_rel_lo(addr)) { | 377 | if (ISAFUNC(uasm_rel_lo(addr))) { |
536 | if (!uasm_in_compat_space_p(addr)) | 378 | if (!ISAFUNC(uasm_in_compat_space_p)(addr)) |
537 | uasm_i_daddiu(buf, rs, rs, uasm_rel_lo(addr)); | 379 | ISAFUNC(uasm_i_daddiu)(buf, rs, rs, |
380 | ISAFUNC(uasm_rel_lo(addr))); | ||
538 | else | 381 | else |
539 | uasm_i_addiu(buf, rs, rs, uasm_rel_lo(addr)); | 382 | ISAFUNC(uasm_i_addiu)(buf, rs, rs, |
383 | ISAFUNC(uasm_rel_lo(addr))); | ||
540 | } | 384 | } |
541 | } | 385 | } |
542 | UASM_EXPORT_SYMBOL(UASM_i_LA); | 386 | UASM_EXPORT_SYMBOL(ISAFUNC(UASM_i_LA)); |
543 | 387 | ||
544 | /* Handle relocations. */ | 388 | /* Handle relocations. */ |
545 | void __uasminit | 389 | void __uasminit |
546 | uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid) | 390 | ISAFUNC(uasm_r_mips_pc16)(struct uasm_reloc **rel, u32 *addr, int lid) |
547 | { | 391 | { |
548 | (*rel)->addr = addr; | 392 | (*rel)->addr = addr; |
549 | (*rel)->type = R_MIPS_PC16; | 393 | (*rel)->type = R_MIPS_PC16; |
550 | (*rel)->lab = lid; | 394 | (*rel)->lab = lid; |
551 | (*rel)++; | 395 | (*rel)++; |
552 | } | 396 | } |
553 | UASM_EXPORT_SYMBOL(uasm_r_mips_pc16); | 397 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_r_mips_pc16)); |
554 | 398 | ||
555 | static inline void __uasminit | 399 | static inline void __uasminit |
556 | __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | 400 | __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab); |
557 | { | ||
558 | long laddr = (long)lab->addr; | ||
559 | long raddr = (long)rel->addr; | ||
560 | |||
561 | switch (rel->type) { | ||
562 | case R_MIPS_PC16: | ||
563 | *rel->addr |= build_bimm(laddr - (raddr + 4)); | ||
564 | break; | ||
565 | |||
566 | default: | ||
567 | panic("Unsupported Micro-assembler relocation %d", | ||
568 | rel->type); | ||
569 | } | ||
570 | } | ||
571 | 401 | ||
572 | void __uasminit | 402 | void __uasminit |
573 | uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | 403 | ISAFUNC(uasm_resolve_relocs)(struct uasm_reloc *rel, struct uasm_label *lab) |
574 | { | 404 | { |
575 | struct uasm_label *l; | 405 | struct uasm_label *l; |
576 | 406 | ||
@@ -579,40 +409,40 @@ uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) | |||
579 | if (rel->lab == l->lab) | 409 | if (rel->lab == l->lab) |
580 | __resolve_relocs(rel, l); | 410 | __resolve_relocs(rel, l); |
581 | } | 411 | } |
582 | UASM_EXPORT_SYMBOL(uasm_resolve_relocs); | 412 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_resolve_relocs)); |
583 | 413 | ||
584 | void __uasminit | 414 | void __uasminit |
585 | uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off) | 415 | ISAFUNC(uasm_move_relocs)(struct uasm_reloc *rel, u32 *first, u32 *end, long off) |
586 | { | 416 | { |
587 | for (; rel->lab != UASM_LABEL_INVALID; rel++) | 417 | for (; rel->lab != UASM_LABEL_INVALID; rel++) |
588 | if (rel->addr >= first && rel->addr < end) | 418 | if (rel->addr >= first && rel->addr < end) |
589 | rel->addr += off; | 419 | rel->addr += off; |
590 | } | 420 | } |
591 | UASM_EXPORT_SYMBOL(uasm_move_relocs); | 421 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_move_relocs)); |
592 | 422 | ||
593 | void __uasminit | 423 | void __uasminit |
594 | uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off) | 424 | ISAFUNC(uasm_move_labels)(struct uasm_label *lab, u32 *first, u32 *end, long off) |
595 | { | 425 | { |
596 | for (; lab->lab != UASM_LABEL_INVALID; lab++) | 426 | for (; lab->lab != UASM_LABEL_INVALID; lab++) |
597 | if (lab->addr >= first && lab->addr < end) | 427 | if (lab->addr >= first && lab->addr < end) |
598 | lab->addr += off; | 428 | lab->addr += off; |
599 | } | 429 | } |
600 | UASM_EXPORT_SYMBOL(uasm_move_labels); | 430 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_move_labels)); |
601 | 431 | ||
602 | void __uasminit | 432 | void __uasminit |
603 | uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, | 433 | ISAFUNC(uasm_copy_handler)(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, |
604 | u32 *end, u32 *target) | 434 | u32 *end, u32 *target) |
605 | { | 435 | { |
606 | long off = (long)(target - first); | 436 | long off = (long)(target - first); |
607 | 437 | ||
608 | memcpy(target, first, (end - first) * sizeof(u32)); | 438 | memcpy(target, first, (end - first) * sizeof(u32)); |
609 | 439 | ||
610 | uasm_move_relocs(rel, first, end, off); | 440 | ISAFUNC(uasm_move_relocs(rel, first, end, off)); |
611 | uasm_move_labels(lab, first, end, off); | 441 | ISAFUNC(uasm_move_labels(lab, first, end, off)); |
612 | } | 442 | } |
613 | UASM_EXPORT_SYMBOL(uasm_copy_handler); | 443 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_copy_handler)); |
614 | 444 | ||
615 | int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) | 445 | int __uasminit ISAFUNC(uasm_insn_has_bdelay)(struct uasm_reloc *rel, u32 *addr) |
616 | { | 446 | { |
617 | for (; rel->lab != UASM_LABEL_INVALID; rel++) { | 447 | for (; rel->lab != UASM_LABEL_INVALID; rel++) { |
618 | if (rel->addr == addr | 448 | if (rel->addr == addr |
@@ -623,88 +453,88 @@ int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) | |||
623 | 453 | ||
624 | return 0; | 454 | return 0; |
625 | } | 455 | } |
626 | UASM_EXPORT_SYMBOL(uasm_insn_has_bdelay); | 456 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_insn_has_bdelay)); |
627 | 457 | ||
628 | /* Convenience functions for labeled branches. */ | 458 | /* Convenience functions for labeled branches. */ |
629 | void __uasminit | 459 | void __uasminit |
630 | uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 460 | ISAFUNC(uasm_il_bltz)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
631 | { | 461 | { |
632 | uasm_r_mips_pc16(r, *p, lid); | 462 | uasm_r_mips_pc16(r, *p, lid); |
633 | uasm_i_bltz(p, reg, 0); | 463 | ISAFUNC(uasm_i_bltz)(p, reg, 0); |
634 | } | 464 | } |
635 | UASM_EXPORT_SYMBOL(uasm_il_bltz); | 465 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bltz)); |
636 | 466 | ||
637 | void __uasminit | 467 | void __uasminit |
638 | uasm_il_b(u32 **p, struct uasm_reloc **r, int lid) | 468 | ISAFUNC(uasm_il_b)(u32 **p, struct uasm_reloc **r, int lid) |
639 | { | 469 | { |
640 | uasm_r_mips_pc16(r, *p, lid); | 470 | uasm_r_mips_pc16(r, *p, lid); |
641 | uasm_i_b(p, 0); | 471 | ISAFUNC(uasm_i_b)(p, 0); |
642 | } | 472 | } |
643 | UASM_EXPORT_SYMBOL(uasm_il_b); | 473 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_b)); |
644 | 474 | ||
645 | void __uasminit | 475 | void __uasminit |
646 | uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 476 | ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
647 | { | 477 | { |
648 | uasm_r_mips_pc16(r, *p, lid); | 478 | uasm_r_mips_pc16(r, *p, lid); |
649 | uasm_i_beqz(p, reg, 0); | 479 | ISAFUNC(uasm_i_beqz)(p, reg, 0); |
650 | } | 480 | } |
651 | UASM_EXPORT_SYMBOL(uasm_il_beqz); | 481 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beqz)); |
652 | 482 | ||
653 | void __uasminit | 483 | void __uasminit |
654 | uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 484 | ISAFUNC(uasm_il_beqzl)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
655 | { | 485 | { |
656 | uasm_r_mips_pc16(r, *p, lid); | 486 | uasm_r_mips_pc16(r, *p, lid); |
657 | uasm_i_beqzl(p, reg, 0); | 487 | ISAFUNC(uasm_i_beqzl)(p, reg, 0); |
658 | } | 488 | } |
659 | UASM_EXPORT_SYMBOL(uasm_il_beqzl); | 489 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beqzl)); |
660 | 490 | ||
661 | void __uasminit | 491 | void __uasminit |
662 | uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1, | 492 | ISAFUNC(uasm_il_bne)(u32 **p, struct uasm_reloc **r, unsigned int reg1, |
663 | unsigned int reg2, int lid) | 493 | unsigned int reg2, int lid) |
664 | { | 494 | { |
665 | uasm_r_mips_pc16(r, *p, lid); | 495 | uasm_r_mips_pc16(r, *p, lid); |
666 | uasm_i_bne(p, reg1, reg2, 0); | 496 | ISAFUNC(uasm_i_bne)(p, reg1, reg2, 0); |
667 | } | 497 | } |
668 | UASM_EXPORT_SYMBOL(uasm_il_bne); | 498 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bne)); |
669 | 499 | ||
670 | void __uasminit | 500 | void __uasminit |
671 | uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 501 | ISAFUNC(uasm_il_bnez)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
672 | { | 502 | { |
673 | uasm_r_mips_pc16(r, *p, lid); | 503 | uasm_r_mips_pc16(r, *p, lid); |
674 | uasm_i_bnez(p, reg, 0); | 504 | ISAFUNC(uasm_i_bnez)(p, reg, 0); |
675 | } | 505 | } |
676 | UASM_EXPORT_SYMBOL(uasm_il_bnez); | 506 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bnez)); |
677 | 507 | ||
678 | void __uasminit | 508 | void __uasminit |
679 | uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 509 | ISAFUNC(uasm_il_bgezl)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
680 | { | 510 | { |
681 | uasm_r_mips_pc16(r, *p, lid); | 511 | uasm_r_mips_pc16(r, *p, lid); |
682 | uasm_i_bgezl(p, reg, 0); | 512 | ISAFUNC(uasm_i_bgezl)(p, reg, 0); |
683 | } | 513 | } |
684 | UASM_EXPORT_SYMBOL(uasm_il_bgezl); | 514 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bgezl)); |
685 | 515 | ||
686 | void __uasminit | 516 | void __uasminit |
687 | uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) | 517 | ISAFUNC(uasm_il_bgez)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) |
688 | { | 518 | { |
689 | uasm_r_mips_pc16(r, *p, lid); | 519 | uasm_r_mips_pc16(r, *p, lid); |
690 | uasm_i_bgez(p, reg, 0); | 520 | ISAFUNC(uasm_i_bgez)(p, reg, 0); |
691 | } | 521 | } |
692 | UASM_EXPORT_SYMBOL(uasm_il_bgez); | 522 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bgez)); |
693 | 523 | ||
694 | void __uasminit | 524 | void __uasminit |
695 | uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg, | 525 | ISAFUNC(uasm_il_bbit0)(u32 **p, struct uasm_reloc **r, unsigned int reg, |
696 | unsigned int bit, int lid) | 526 | unsigned int bit, int lid) |
697 | { | 527 | { |
698 | uasm_r_mips_pc16(r, *p, lid); | 528 | uasm_r_mips_pc16(r, *p, lid); |
699 | uasm_i_bbit0(p, reg, bit, 0); | 529 | ISAFUNC(uasm_i_bbit0)(p, reg, bit, 0); |
700 | } | 530 | } |
701 | UASM_EXPORT_SYMBOL(uasm_il_bbit0); | 531 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bbit0)); |
702 | 532 | ||
703 | void __uasminit | 533 | void __uasminit |
704 | uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg, | 534 | ISAFUNC(uasm_il_bbit1)(u32 **p, struct uasm_reloc **r, unsigned int reg, |
705 | unsigned int bit, int lid) | 535 | unsigned int bit, int lid) |
706 | { | 536 | { |
707 | uasm_r_mips_pc16(r, *p, lid); | 537 | uasm_r_mips_pc16(r, *p, lid); |
708 | uasm_i_bbit1(p, reg, bit, 0); | 538 | ISAFUNC(uasm_i_bbit1)(p, reg, bit, 0); |
709 | } | 539 | } |
710 | UASM_EXPORT_SYMBOL(uasm_il_bbit1); | 540 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bbit1)); |