1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
29 #include "libiberty.h"
31 #include "bfd_stdint.h"
33 #define __MF(v, off, bs) ((v & ((1 << (bs)) - 1)) << (off))
34 #define __GF(v, off, bs) ((v >> (off)) & ((1 << (bs)) - 1))
35 #define __PF(v, off, bs, val) do { v = __put_field (v, off, bs, val); } while (0)
36 /* #define __SEXT(v, bs) ((v ^ (1 << (bs - 1))) - (1 << (bs - 1))) */
37 #define __SEXT(v, bs) (((v & ((1 << bs) - 1)) ^ (1 << (bs - 1))) - (1 << (bs - 1)))
38 #define __BIT(n) (1 << n)
41 #define OP6(insn) ((insn >> 25) & 0x3F)
42 #define RT5(insn) ((insn >> 20) & 0x1F)
43 #define RA5(insn) ((insn >> 15) & 0x1F)
44 #define RB5(insn) ((insn >> 10) & 0x1F)
45 #define RD5(insn) ((insn >> 5) & 0x1F)
46 #define SUB5(insn) ((insn >> 0) & 0x1F)
47 #define SUB10(insn) ((insn >> 0) & 0x3FF)
48 #define IMMU(insn, bs) (insn & ((1 << bs) - 1))
49 #define IMMS(insn, bs) __SEXT ((insn & ((1 << bs) - 1)), bs)
50 #define IMM1U(insn) IMMU ((insn >> 10), 5)
51 #define IMM1S(insn) IMMS ((insn >> 10), 5)
52 #define IMM2U(insn) IMMU ((insn >> 5), 5)
53 #define IMM2S(insn) IMMS ((insn >> 5), 5)
55 /* Default text to print if an instruction isn't recognized. */
56 #define UNKNOWN_INSN_MSG _("*unknown*")
58 static const char *mnemonic_op6
[] =
60 "lbi", "lhi", "lwi", "ldi", "lbi.bi", "lhi.bi", "lwi.bi", "ldi.bi",
61 "sbi", "shi", "swi", "sdi", "sbi.bi", "shi.bi", "swi.bi", "sdi.bi",
62 "lbsi", "lhsi", "lwsi", "dprefi", "lbsi.bi", "lhsi.bi", "lwsi.bi", "lbgp",
63 "lwc", "swc", "ldc", "sdc", "mem", "lsmw", "hwgp", "sbgp",
64 "alu1", "alu2", "movi", "sethi", "ji", "jreg", "br1", "br2",
65 "addi", "subri", "andi", "xori", "ori", "br3", "slti", "sltsi",
66 "aext", "cext", "misc", "bitci", "op_64", "cop"
69 static const char *mnemonic_mem
[] =
71 "lb", "lh", "lw", "ld", "lb.bi", "lh.bi", "lw.bi", "ld.bi",
72 "sb", "sh", "sw", "sd", "sb.bi", "sh.bi", "sw.bi", "sd.bi",
73 "lbs", "lhs", "lws", "dpref", "lbs.bi", "lhs.bi", "lws.bi", "27",
74 "llw", "scw", "32", "33", "34", "35", "36", "37",
75 "lbup", "41", "lwup", "43", "44", "45", "46", "47",
79 static const char *mnemonic_alu1
[] =
81 "add", "sub", "and", "xor", "or", "nor", "slt", "slts",
82 "slli", "srli", "srai", "rotri", "sll", "srl", "sra", "rotr",
83 "seb", "seh", "bitc", "zeh", "wsbh", "or_srli", "divsr", "divr",
84 "sva", "svs", "cmovz", "cmovn", "add_srli", "sub_srli", "and_srli", "xor_srli"
88 static const char *mnemonic_alu20
[] =
90 "max", "min", "ave", "abs", "clips", "clip", "clo", "clz",
91 "bset", "bclr", "btgl", "btst", "bse", "bsp", "ffb", "ffmism",
92 "add.sc", "sub.sc", "add.wc", "sub.wc", "24", "25", "26", "ffzmism",
93 "qadd", "qsub", "32", "33", "34", "35", "36", "37",
94 "mfusr", "mtusr", "42", "43", "mul", "45", "46", "47",
95 "mults64", "mult64", "madds64", "madd64", "msubs64", "msub64", "divs", "div",
96 "60", "mult32", "62", "madd32", "64", "msub32", "65", "66",
97 "dmadd", "dmaddc", "dmsub", "dmsubc", "rmfhi", "qmflo"
100 static const char *mnemonic_alu21
[] =
102 "00", "01", "02", "03", "04", "05", "06", "07",
103 "10", "11", "12", "13", "14", "15", "ffbi", "flmism",
104 "20", "21", "22", "23", "24", "25", "26", "27",
105 "30", "31", "32", "33", "34", "35", "36", "37",
106 "40", "41", "42", "43", "44", "45", "46", "47",
107 "mulsr64", "mulr64", "52", "53", "54", "55", "56", "57",
108 "60", "61", "62", "maddr32", "64", "msubr32", "66", "67",
109 "70", "71", "72", "73", "74", "75", "76", "77"
112 static const char *mnemonic_br2
[] =
114 "ifcall", "01", "beqz", "bnez", "bgez", "bltz", "bgtz", "blez",
115 "10", "11", "12", "13", "bgezal", "bltzal"
118 static const char *mnemonic_misc
[] =
120 "standby", "cctl", "mfsr", "mtsr", "iret", "trap", "teqz", "tnez",
121 "dsb", "isb", "break", "syscall", "msync", "isync", "tlbop"
124 static const char *mnemonic_hwgp
[] =
126 "lhi.gp", "lhi.gp", "lhsi.gp", "lhsi.gp",
127 "shi.gp", "shi.gp", "lwi.gp", "swi.gp"
130 static const char *keyword_dpref
[] =
132 "SRD", "MRD", "SWR", "MWR", "PTE", "CLWR", "6", "7",
133 "8", "9", "10", "11", "12", "13", "14", "15"
136 static const char *mnemonic_alu
[] =
138 "fadds", "fsubs", "fcpynss", "fcpyss", "fmadds",
139 "fmsubs", "fcmovns", "fcmovzs", "fnmadds", "fnmsubs",
140 "10", "11", "fmuls", "fdivs", "faddd",
141 "fsubd", "fcpynsd", "fcpysd", "fmaddd", "fmsubd",
142 "fcmovnd", "fcmovzd", "fnmaddd", "fnmsubd", "24",
143 "25", "fmuld", "fdivd"
146 static const char *mnemonic_fpu_2op
[] =
148 "fs2d", "fsqrts", "2", "3", "4", "fabss", "6", "7",
149 "fui2s", "9", "10", "11", "fsi2s", "13", "14", "15",
150 "fs2ui", "17", "18", "19", "fs2ui.z", "21", "22", "23",
151 "fs2si", "25", "26", "27", "fs2si.z", "fd2s", "fsqrtd", "31",
152 "32", "33", "fabsd", "35", "36", "fui2d", "38", "39",
153 "40", "fsi2d", "42", "43", "44", "fd2ui", "46", "47",
154 "48", "fd2ui.z", "50", "51", "52", "fd2si", "54", "55",
158 static const char *mnemonic_fs2_cmp
[] =
160 "fcmpeqs", "fcmpeqs.e", "fcmplts", "fcmplts.e",
161 "fcmples", "fcmples.e", "fcmpuns", "fcmpuns.e"
164 static const char *mnemonic_fd2_cmp
[] =
166 "fcmpeqd", "fcmpeqd.e", "fcmpltd", "fcmpltd.e",
167 "fcmpled", "fcmpled.e", "fcmpund", "fcmpund.e"
170 static const char *gpr_map
[] =
172 "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7",
173 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
174 "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23",
175 "$r24", "$r25", "$r26", "$r27", "$fp", "$gp", "$lp", "$sp"
178 static const char *usr_map
[][32] =
181 "d0,lo", "d0.hi", "d1,lo", "d1,hi", "4", "5", "6", "7",
182 "8", "9", "10", "11", "12", "13", "14", "15",
183 "16", "17", "18", "19", "20", "21", "22", "23",
184 "24", "25", "26", "27", "28", "29", "30", "pc"
187 "DMA_CFG", "DMA_GCSW", "DMA_CHNSEL", "DMA_ACT", "DMA_SETUP",
188 "DMA_ISADDR", "DMA_ESADDR", "DMA_TCNT", "DMA_STATUS", "DMA_2DSET",
189 "10", "11", "12", "13", "14",
190 "15", "16,", "17", "18", "19",
191 "20", "21", "22", "23", "24,",
195 "PFMC0", "PFMC1", "PFMC2", "3", "PFMCTL"
200 print_insn16 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
)
202 static char r4map
[] =
204 0, 1, 2, 3, 4, 5, 6, 7,
205 8, 9, 10, 11, 16, 17, 18, 19
207 const int rt5
= __GF (insn
, 5, 5);
208 const int ra5
= __GF (insn
, 0, 5);
209 const int rt4
= r4map
[__GF (insn
, 5, 4)];
210 const int imm5u
= IMMU (insn
, 5);
211 const int imm9u
= IMMU (insn
, 9);
212 const int rt3
= __GF (insn
, 6, 3);
213 const int ra3
= __GF (insn
, 3, 3);
214 const int rb3
= __GF (insn
, 0, 3);
215 const int rt38
= __GF (insn
, 8, 3);
216 const int imm3u
= rb3
;
217 fprintf_ftype func
= info
->fprintf_func
;
218 void *stream
= info
->stream
;
220 static const char *mnemonic_96
[] =
222 "0x1", "0x1", "0x2", "0x3",
223 "add45", "sub45", "addi45", "subi45",
224 "srai45", "srli45", "slli333", "0xb",
225 "add333", "sub333", "addi333", "subi333",
226 "lwi333", "lwi333.bi", "lhi333", "lbi333",
227 "swi333", "swi333.bi", "shi333", "sbi333",
228 "addri36.sp", "lwi45.fe", "lwi450", "swi450",
229 "0x1c", "0x1d", "0x1e", "0x1f",
230 "0x20", "0x21", "0x22", "0x23",
231 "0x24", "0x25", "0x26", "0x27,"
232 "0x28", "0x29", "0x2a", "0x2b",
233 "0x2c", "0x2d", "0x2e", "0x2f,"
234 "slts45", "slt45", "sltsi45", "slti45",
235 "0x34", "0x35", "0x36", "0x37",
236 "0x38", "0x39", "0x3a", "0x3b",
240 static const char *mnemonic_misc33
[] =
242 "misc33_0", "misc33_1", "neg33", "not33", "mul33", "xor33", "and33", "or33",
245 static const char *mnemonic_0xb
[] =
247 "zeb33", "zeh33", "seb33", "seh33", "xlsb33", "x11b33", "bmski33", "fexti33"
250 static const char *mnemonic_bnes38
[] =
252 "jr5", "jral5", "ex9.it", "?", "ret5", "add5.pc"
255 switch (__GF (insn
, 7, 8))
257 case 0xf8: /* push25 */
258 case 0xf9: /* pop25 */
260 uint32_t res
[] = { 6, 8, 10, 14 };
261 uint32_t re
= res
[__GF (insn
, 5, 2)];
263 func (stream
, "%s\t%s, %d", (insn
& __BIT (7)) ? "pop25" : "push25",
264 gpr_map
[re
], imm5u
<< 3);
269 if (__GF (insn
, 8, 7) == 0x7d) /* movd44 */
271 int rt5e
= __GF (insn
, 4, 4) << 1;
272 int ra5e
= IMMU (insn
, 4) << 1;
274 func (stream
, "movd44\t%s, %d", gpr_map
[rt5e
], ra5e
);
278 switch (__GF (insn
, 9, 6))
280 case 0x4: /* add45 */
281 case 0x5: /* sub45 */
282 case 0x30: /* slts45 */
283 case 0x31: /* slt45 */
284 func (stream
, "%s\t%s, %s", mnemonic_96
[__GF (insn
, 9, 6)],
285 gpr_map
[rt4
], gpr_map
[ra5
]);
287 case 0x6: /* addi45 */
288 case 0x7: /* subi45 */
289 case 0x8: /* srai45 */
290 case 0x9: /* srli45 */
291 case 0x32: /* sltsi45 */
292 case 0x33: /* slti45 */
293 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
296 case 0xc: /* add333 */
297 case 0xd: /* sub333 */
298 func (stream
, "%s\t%s, %s, %s", mnemonic_96
[__GF (insn
, 9, 6)],
299 gpr_map
[rt3
], gpr_map
[ra3
], gpr_map
[rb3
]);
301 case 0xa: /* slli333 */
302 case 0xe: /* addi333 */
303 case 0xf: /* subi333 */
304 func (stream
, "%s\t%s, %s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
305 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
);
307 case 0x10: /* lwi333 */
308 case 0x14: /* swi333 */
309 func (stream
, "%s\t%s, [%s + %d]", mnemonic_96
[__GF (insn
, 9, 6)],
310 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
<< 2);
312 case 0x12: /* lhi333 */
313 case 0x16: /* shi333 */
314 func (stream
, "%s\t%s, [%s + %d]", mnemonic_96
[__GF (insn
, 9, 6)],
315 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
<< 1);
317 case 0x13: /* lbi333 */
318 case 0x17: /* sbi333 */
319 func (stream
, "%s\t%s, [%s + %d]", mnemonic_96
[__GF (insn
, 9, 6)],
320 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
);
322 case 0x11: /* lwi333.bi */
323 case 0x15: /* swi333.bi */
324 func (stream
, "%s\t%s, [%s], %d", mnemonic_96
[__GF (insn
, 9, 6)],
325 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
<< 2);
327 case 0x18: /* addri36.sp */
328 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
329 gpr_map
[rt3
], IMMU (insn
, 6) << 2);
331 case 0x19: /* lwi45.fe */
332 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
333 gpr_map
[rt4
], -((32 - imm5u
) << 2));
335 case 0x1a: /* lwi450 */
336 case 0x1b: /* swi450 */
337 func (stream
, "%s\t%s, [%s]", mnemonic_96
[__GF (insn
, 9, 6)],
338 gpr_map
[rt4
], gpr_map
[ra5
]);
340 case 0x34: /* beqzs8, bnezs8 */
341 func (stream
, "%s\t", ((insn
& __BIT (8)) ? "bnezs8" : "beqzs8"));
342 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
344 case 0x35: /* break16, ex9.it */
345 /* FIXME: Check bfd_mach. */
346 if (imm9u
< 32) /* break16 */
347 func (stream
, "break16\t%d", imm9u
);
349 func (stream
, "ex9.it\t%d", imm9u
);
351 case 0x3c: /* ifcall9 */
352 func (stream
, "%s\t", mnemonic_96
[__GF (insn
, 9, 6)]);
353 info
->print_address_func ((IMMU (insn
, 9) << 1) + pc
, info
);
355 case 0x3d: /* movpi45 */
356 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
357 gpr_map
[rt4
], ra5
+ 16);
359 case 0x3f: /* MISC33 */
360 func (stream
, "%s\t%s, %s", mnemonic_misc33
[rb3
],
361 gpr_map
[rt3
], gpr_map
[ra3
]);
364 func (stream
, "%s\t%s, %s", mnemonic_0xb
[rb3
],
365 gpr_map
[rt3
], gpr_map
[ra3
]);
369 switch (__GF (insn
, 10, 5))
371 case 0x0: /* mov55 or ifret16 */
372 /* FIXME: Check bfd_mach. */
373 if (rt5
== ra5
&& rt5
== 31)
374 func (stream
, "ifret16");
376 func (stream
, "mov55\t%s, %s", gpr_map
[rt5
], gpr_map
[ra5
]);
378 case 0x1: /* movi55 */
379 func (stream
, "movi55\t%s, %d", gpr_map
[rt5
], IMMS (insn
, 5));
381 case 0x1b: /* addi10s (V2) */
382 func (stream
, "addi10s\t%d", IMMS (insn
, 10));
386 switch (__GF (insn
, 11, 4))
388 case 0x7: /* lwi37.fp/swi37.fp */
389 func (stream
, "%s\t%s, [$fp + 0x%x]",
390 ((insn
& __BIT (7)) ? "swi37" : "lwi37"),
391 gpr_map
[rt38
], IMMU (insn
, 7) << 2);
393 case 0x8: /* beqz38 */
394 case 0x9: /* bnez38 */
395 func (stream
, "%s\t%s, ",
396 ((__GF (insn
, 11, 4) & 1) ? "bnez38" : "beqz38"), gpr_map
[rt38
]);
397 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
399 case 0xa: /* beqs38/j8, implied r5 */
402 func (stream
, "j8\t");
403 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
407 func (stream
, "beqs38\t%s, ", gpr_map
[rt38
]);
408 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
411 case 0xb: /* bnes38 and others */
414 switch (__GF (insn
, 5, 3))
419 func (stream
, "%s\t%s", mnemonic_bnes38
[__GF (insn
, 5, 3)],
422 case 2: /* ex9.it imm5 */
423 case 5: /* add5.pc */
424 func (stream
, "%s\t%d", mnemonic_bnes38
[__GF (insn
, 5, 3)], ra5
);
427 func (stream
, UNKNOWN_INSN_MSG
);
433 func (stream
, "bnes38\t%s", gpr_map
[rt3
]);
434 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
437 case 0xe: /* lwi37/swi37 */
438 func (stream
, "%s\t%s, [+ 0x%x]",
439 ((insn
& __BIT (7)) ? "swi37.sp" : "lwi37.sp"),
440 gpr_map
[rt38
], IMMU (insn
, 7) << 2);
447 print_insn32_mem (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
,
450 const int rt
= RT5 (insn
);
451 const int ra
= RA5 (insn
);
452 const int rb
= RB5 (insn
);
453 const int sv
= __GF (insn
, 8, 2);
454 const int op
= insn
& 0xFF;
455 fprintf_ftype func
= info
->fprintf_func
;
456 void *stream
= info
->stream
;
473 case 0x20: /* lbup */
474 case 0x22: /* lwup */
475 case 0x28: /* sbup */
476 case 0x2a: /* swup */
477 func (stream
, "%s\t%s, [%s + (%s << %d)]",
478 mnemonic_mem
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], sv
);
480 case 0x4: /* lb.bi */
481 case 0x5: /* lh.bi */
482 case 0x6: /* lw.bi */
483 case 0x7: /* ld.bi */
484 case 0xc: /* sb.bi */
485 case 0xd: /* sh.bi */
486 case 0xe: /* sw.bi */
487 case 0xf: /* sd.bi */
488 case 0x14: /* lbs.bi */
489 case 0x15: /* lhs.bi */
490 case 0x16: /* lws.bi */
491 func (stream
, "%s\t%s, [%s], (%s << %d)",
492 mnemonic_mem
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], sv
);
494 case 0x13: /* dpref */
496 const char *subtype
= "???";
498 if ((rt
& 0xf) < ARRAY_SIZE (keyword_dpref
))
499 subtype
= keyword_dpref
[rt
& 0xf];
501 func (stream
, "%s\t%s, [%s + (%s << %d)]",
502 "dpref", subtype
, gpr_map
[ra
], gpr_map
[rb
], sv
);
506 func (stream
, UNKNOWN_INSN_MSG
);
512 print_insn32_alu1 (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
, uint32_t insn
)
514 int op
= insn
& 0x1f;
515 const int rt
= RT5 (insn
);
516 const int ra
= RA5 (insn
);
517 const int rb
= RB5 (insn
);
518 const int rd
= RD5 (insn
);
519 fprintf_ftype func
= info
->fprintf_func
;
520 void *stream
= info
->stream
;
524 case 0x0: /* add, add_slli */
525 case 0x1: /* sub, sub_slli */
526 case 0x2: /* and, add_slli */
527 case 0x3: /* xor, xor_slli */
528 case 0x4: /* or, or_slli */
531 func (stream
, "%s_slli\t%s, %s, %s, #%d",
532 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], rd
);
536 func (stream
, "%s\t%s, %s, %s",
537 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
540 case 0x1c: /* add_srli */
541 case 0x1d: /* sub_srli */
542 case 0x1e: /* and_srli */
543 case 0x1f: /* xor_srli */
544 case 0x15: /* or_srli */
545 func (stream
, "%s\t%s, %s, %s, #%d",
546 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], rd
);
555 case 0x12: /* bitc */
558 case 0x1a: /* cmovz */
559 case 0x1b: /* cmovn */
560 func (stream
, "%s\t%s, %s, %s",
561 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
564 if (ra
==0 && rb
== 0 && rb
==0)
566 func (stream
, "nop");
571 case 0xb: /* rotri */
572 func (stream
, "%s\t%s, %s, #%d",
573 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], rb
);
578 case 0x14: /* wsbh */
579 func (stream
, "%s\t%s, %s",
580 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
]);
582 case 0x16: /* divsr */
583 case 0x17: /* divr */
584 func (stream
, "%s\t%s, %s, %s, %s",
585 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[rd
], gpr_map
[ra
], gpr_map
[rb
]);
588 func (stream
, UNKNOWN_INSN_MSG
);
596 print_insn32_alu2 (bfd_vma pc ATTRIBUTE_UNUSED
,
597 disassemble_info
*info
,
600 int op
= insn
& 0x3ff;
601 const int rt
= RT5 (insn
);
602 const int ra
= RA5 (insn
);
603 const int rb
= RB5 (insn
);
604 fprintf_ftype func
= info
->fprintf_func
;
605 void *stream
= info
->stream
;
607 if ((insn
& 0x7f) == 0x4e) /* ffbi */
609 func (stream
, "ffbi\t%s, %s, #0x%x",
610 gpr_map
[rt
], gpr_map
[ra
], __GF (insn
, 7, 8));
622 case 0xf: /* ffmism */
623 case 0x17: /* ffzmism */
625 func (stream
, "%s\t%s, %s, %s", mnemonic_alu20
[op
],
626 gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
632 func (stream
, "%s\t%s, %s", mnemonic_alu20
[op
], gpr_map
[rt
], gpr_map
[ra
]);
635 case 0x4: /* clips */
641 func (stream
, "%s\t%s, %s, #%d", mnemonic_alu20
[op
],
642 gpr_map
[rt
], gpr_map
[ra
], IMM1U (insn
));
645 case 0x20: /* mfusr */
646 case 0x21: /* mtusr */
647 func (stream
, "%s\t%s, $%s", mnemonic_alu20
[op
],
648 gpr_map
[rt
], usr_map
[__GF (insn
, 10, 5)][__GF (insn
, 15, 5)]);
650 case 0x28: /* mults64 */
651 case 0x29: /* mult64 */
652 case 0x2a: /* madds64 */
653 case 0x2b: /* madd64 */
654 case 0x2c: /* msubs64 */
655 case 0x2d: /* msub64 */
656 case 0x2e: /* divs */
658 case 0x31: /* mult32 */
659 case 0x33: /* madd32 */
660 case 0x35: /* msub32 */
661 func (stream
, "%s\t$d%d, %s, %s", mnemonic_alu20
[op
],
662 rt
>> 1, gpr_map
[ra
], gpr_map
[rb
]);
665 case 0x4f: /* flmism */
666 case 0x68: /* mulsr64 */
667 case 0x69: /* mulr64 */
668 case 0x73: /* maddr32 */
669 case 0x75: /* msubr32 */
671 func (stream
, "%s\t%s, %s, %s", mnemonic_alu21
[op
],
672 gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
675 func (stream
, UNKNOWN_INSN_MSG
);
681 print_insn32_jreg (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
, uint32_t insn
)
683 int op
= insn
& 0xff;
684 const int rt
= RT5 (insn
);
685 const int rb
= RB5 (insn
);
686 const char *dtit_on
[] = { "", ".iton", ".dton", ".ton" };
687 const char *dtit_off
[] = { "", ".itoff", ".dtoff", ".toff" };
688 const char *mnemonic_jreg
[] = { "jr", "jral", "jrnez", "jralnez" };
689 const char *mnemonic_ret
[] = { "jr", "ret", NULL
, "ifret" };
690 const int dtit
= __GF (insn
, 8, 2);
691 fprintf_ftype func
= info
->fprintf_func
;
692 void *stream
= info
->stream
;
697 func (stream
, "%s%s\t%s", mnemonic_ret
[op
>> 5],
698 dtit_on
[dtit
], gpr_map
[rb
]);
702 func (stream
, "%s%s\t%s", mnemonic_ret
[op
>> 5],
703 dtit_off
[dtit
], gpr_map
[rb
]);
705 case 0x60: /* ifret */
709 case 3: /* jralnez */
710 func (stream
, "%s%s\t%s, %s", mnemonic_jreg
[op
],
711 dtit_on
[dtit
], gpr_map
[rt
], gpr_map
[rb
]);
713 default: /* unknown */
714 func (stream
, UNKNOWN_INSN_MSG
);
720 print_insn32_misc (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
,
723 int op
= insn
& 0x1f;
726 fprintf_ftype func
= info
->fprintf_func
;
727 void *stream
= info
->stream
;
729 static const char *keyword_standby
[] =
731 "no_wake_grant", "wake_grant", "wait_done",
733 static const char *keyword_tlbop
[] =
735 "TRD", "TWR", "RWR", "RWLK", "UNLK", "PB", "INV", "FLUA"
740 case 0x0: /* standby */
741 id
= __GF (insn
, 5, 20);
742 if (id
< ARRAY_SIZE (keyword_standby
))
743 func (stream
, "standby\t%s", keyword_standby
[id
]);
745 func (stream
, "standby\t%d", id
);
748 func (stream
, "cctl\t!FIXME");
752 case 0xd: /* isync */
753 case 0xc: /* msync */
755 func (stream
, "%s", mnemonic_misc
[op
]);
758 case 0xa: /* break */
759 case 0xb: /* syscall */
760 id
= __GF (insn
, 5, 15);
761 func (stream
, "%s\t%d", mnemonic_misc
[op
], id
);
765 /* FIXME: setend, setgie. */
766 id
= __GF (insn
, 10, 10);
767 func (stream
, "%s\t%s, %d", mnemonic_misc
[op
], gpr_map
[rt
], id
);
771 id
= __GF (insn
, 5, 15);
772 func (stream
, "%s\t%s, %d", mnemonic_misc
[op
], gpr_map
[rt
], id
);
774 case 0xe: /* tlbop */
775 id
= __GF (insn
, 5, 5);
776 if (id
< ARRAY_SIZE (keyword_tlbop
))
777 func (stream
, "tlbop\t%s", keyword_tlbop
[id
]);
779 func (stream
, "tlbop\t%d", id
);
785 print_insn32_fpu (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
,
789 int mask_sub_op
= (insn
& 0x3c0) >> 6;
790 int mask_bi
= (insn
& 0x80) >> 7;
791 int mask_cfg
= (insn
& 0x7c00) >> 10;
792 int mask_f2op
= (insn
& 0x7c00) >> 10;
796 const int rt
= RT5 (insn
);
797 const int ra
= RA5 (insn
);
798 const int rb
= RB5 (insn
);
799 const int sv
= __GF (insn
, 8, 2);
800 fprintf_ftype func
= info
->fprintf_func
;
801 void *stream
= info
->stream
;
807 dp
= (op
& 0x8) ? 1 : 0;
830 func (stream
, "%s\t$f%c%d, $f%c%d, $f%c%d",
831 mnemonic_alu
[mask_sub_op
+ dp_insn
],
832 wd
, rt
, wd
, ra
, wd
, rb
);
836 func (stream
, "%s\t$f%c%d, $f%c%d, $fs%d",
837 mnemonic_alu
[mask_sub_op
+ dp_insn
],
856 func (stream
, "%s\t$fs%d, $fd%d",
857 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], rt
, ra
);
859 func (stream
, "%s\t$fd%d, $fs%d",
860 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], rt
, ra
);
864 func (stream
, "%s\t$f%c%d, $f%c%d",
865 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], wd
, rt
, wd
, ra
);
869 func (stream
, "%s\t$f%c%d, $fs%d",
870 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], wd
, rt
, ra
);
876 func (stream
, "%s\t$fs%d, $f%c%d",
877 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], rt
, wd
, ra
);
885 func (stream
, "fmfsr\t%s, $fs%d", gpr_map
[rt
], ra
);
888 func (stream
, "fmfdr\t%s, $fd%d", gpr_map
[rt
], ra
);
892 func (stream
, "fmfcsr\t%s", gpr_map
[rt
]);
894 func (stream
, "fmfcfg\t%s", gpr_map
[rt
]);
899 func (stream
, "fls.bi\t$fs%d, [%s], (%s << %d)",
900 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
902 func (stream
, "fls\t$fs%d, [%s + (%s << %d)]",
903 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
907 func (stream
, "fld.bi\t$fd%d, [%s], (%s << %d)",
908 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
910 func (stream
, "fld\t$fd%d, [%s + (%s << %d)]",
911 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
914 func (stream
, "%s\t$fs%d, $fs%d, $fs%d",
915 mnemonic_fs2_cmp
[mask_sub_op
], rt
, ra
, rb
);
921 func (stream
, "fmtsr\t%s, $fs%d", gpr_map
[rt
], ra
);
924 func (stream
, "fmtdr\t%s, $fd%d", gpr_map
[rt
], ra
);
927 func (stream
, "fmtcsr\t%s", gpr_map
[rt
]);
932 func (stream
, "fss.bi\t$fs%d, [%s], (%s << %d)",
933 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
935 func (stream
, "fss\t$fs%d, [%s + (%s << %d)]",
936 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
940 func (stream
, "fsd.bi\t$fd%d, [%s], (%s << %d)",
941 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
943 func (stream
, "fsd\t$fd%d, [%s + (%s << %d)]",
944 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
947 func (stream
, "%s\t$fs%d, $fd%d, $fd%d",
948 mnemonic_fd2_cmp
[mask_sub_op
], rt
, ra
, rb
);
954 print_insn32 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
)
957 const int rt
= RT5 (insn
);
958 const int ra
= RA5 (insn
);
959 const int rb
= RB5 (insn
);
960 const int imm15s
= IMMS (insn
, 15);
961 const int imm15u
= IMMU (insn
, 15);
963 fprintf_ftype func
= info
->fprintf_func
;
964 void *stream
= info
->stream
;
976 case 0x10: /* lbsi */
977 case 0x11: /* lhsi */
978 case 0x12: /* lwsi */
980 func (stream
, "%s\t%s, [%s + #%d]",
981 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15s
<< shift
);
983 case 0x4: /* lbi.bi */
984 case 0x5: /* lhi.bi */
985 case 0x6: /* lwi.bi */
986 case 0x7: /* ldi.bi */
987 case 0xc: /* sbi.bi */
988 case 0xd: /* shi.bi */
989 case 0xe: /* swi.bi */
990 case 0xf: /* sdi.bi */
991 case 0x14: /* lbsi.bi */
992 case 0x15: /* lhsi.bi */
993 case 0x16: /* lwsi.bi */
995 func (stream
, "%s\t%s, [%s], #%d",
996 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15s
<< shift
);
998 case 0x13: /* dprefi */
1000 const char *subtype
= "???";
1012 if ((rt
& 0xf) < ARRAY_SIZE (keyword_dpref
))
1013 subtype
= keyword_dpref
[rt
& 0xf];
1015 func (stream
, "%s.%c\t%s, [%s + #%d]",
1016 mnemonic_op6
[op
], wd
, subtype
, gpr_map
[ra
], imm15s
<< shift
);
1019 case 0x17: /* LBGP */
1020 func (stream
, "%s\t%s, [+ %d]",
1021 ((insn
& __BIT (19)) ? "lbsi.gp" : "lbi.gp"),
1022 gpr_map
[rt
], IMMS (insn
, 19));
1024 case 0x18: /* LWC */
1025 case 0x19: /* SWC */
1026 case 0x1a: /* LDC */
1027 case 0x1b: /* SDC */
1028 if (__GF (insn
, 13, 2) == 0)
1030 char ls
= (op
& 1) ? 's' : 'l';
1031 char wd
= (op
& 2) ? 'd' : 's';
1033 if (insn
& __BIT (12))
1035 func (stream
, "f%c%ci.bi\t$f%c%d, [%s], %d", ls
, wd
,
1036 wd
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1040 func (stream
, "f%c%ci\t$f%c%d, [%s + %d]", ls
, wd
,
1041 wd
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1046 char ls
= (op
& 1) ? 's' : 'l';
1047 char wd
= (op
& 2) ? 'd' : 'w';
1048 int cp
= __GF (insn
, 13, 2);
1050 if (insn
& __BIT (12))
1052 func (stream
, "cp%c%ci\tcp%d, $cpr%d, [%s], %d", ls
, wd
,
1053 cp
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1057 func (stream
, "cp%c%ci\tcp%d, $cpr%d, [%s + %d]", ls
, wd
,
1058 cp
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1062 case 0x1c: /* MEM */
1063 print_insn32_mem (pc
, info
, insn
);
1065 case 0x1d: /* LSMW */
1067 int enb4
= __GF (insn
, 6, 4);
1068 char ls
= (insn
& __BIT (5)) ? 's' : 'l';
1069 char ab
= (insn
& __BIT (4)) ? 'a' : 'b';
1070 char *di
= (insn
& __BIT (3)) ? "d" : "i";
1071 char *m
= (insn
& __BIT (2)) ? "m" : "";
1072 static const char *s
[] = {"", "a", "zb", "?"};
1074 /* lsmwzb only always increase. */
1075 if ((insn
& 0x3) == 2)
1078 func (stream
, "%cmw%s.%c%s%s\t%s, [%s], %s, 0x%x",
1079 ls
, s
[insn
& 0x3], ab
, di
, m
, gpr_map
[rt
],
1080 gpr_map
[ra
], gpr_map
[rb
], enb4
);
1083 case 0x1e: /* HWGP */
1084 op
= __GF (insn
, 17, 3);
1087 case 0: case 1: /* lhi.gp */
1088 case 2: case 3: /* lhsi.gp */
1089 case 4: case 5: /* shi.gp */
1090 func (stream
, "%s\t%s, [+ %d]",
1091 mnemonic_hwgp
[op
], gpr_map
[rt
], IMMS (insn
, 18) << 1);
1093 case 6: /* lwi.gp */
1094 case 7: /* swi.gp */
1095 func (stream
, "%s\t%s, [+ %d]",
1096 mnemonic_hwgp
[op
], gpr_map
[rt
], IMMS (insn
, 17) << 2);
1100 case 0x1f: /* SBGP */
1101 if (insn
& __BIT (19))
1102 func (stream
, "addi.gp\t%s, %d",
1103 gpr_map
[rt
], IMMS (insn
, 19));
1105 func (stream
, "sbi.gp\t%s, [+ %d]",
1106 gpr_map
[rt
], IMMS (insn
, 19));
1108 case 0x20: /* ALU_1 */
1109 print_insn32_alu1 (pc
, info
, insn
);
1111 case 0x21: /* ALU_2 */
1112 print_insn32_alu2 (pc
, info
, insn
);
1114 case 0x22: /* movi */
1115 func (stream
, "movi\t%s, %d", gpr_map
[rt
], IMMS (insn
, 20));
1117 case 0x23: /* sethi */
1118 func (stream
, "sethi\t%s, 0x%x", gpr_map
[rt
], IMMU (insn
, 20));
1120 case 0x24: /* ji, jal */
1121 /* FIXME: Handle relocation. */
1122 if (info
->flags
& INSN_HAS_RELOC
)
1124 func (stream
, "%s\t", ((insn
& __BIT (24)) ? "jal" : "j"));
1125 info
->print_address_func ((IMMS (insn
, 24) << 1) + pc
, info
);
1127 case 0x25: /* jreg */
1128 print_insn32_jreg (pc
, info
, insn
);
1130 case 0x26: /* br1 */
1131 func (stream
, "%s\t%s, %s, ", ((insn
& __BIT (14)) ? "bne" : "beq"),
1132 gpr_map
[rt
], gpr_map
[ra
]);
1133 info
->print_address_func ((IMMS (insn
, 14) << 1) + pc
, info
);
1135 case 0x27: /* br2 */
1136 func (stream
, "%s\t%s, ", mnemonic_br2
[__GF (insn
, 16, 4)],
1138 info
->print_address_func ((IMMS (insn
, 16) << 1) + pc
, info
);
1140 case 0x28: /* addi */
1141 case 0x2e: /* slti */
1142 case 0x2f: /* sltsi */
1143 case 0x29: /* subri */
1144 func (stream
, "%s\t%s, %s, %d",
1145 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15s
);
1147 case 0x2a: /* andi */
1148 case 0x2b: /* xori */
1149 case 0x2c: /* ori */
1150 case 0x33: /* bitci */
1151 func (stream
, "%s\t%s, %s, %d",
1152 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15u
);
1154 case 0x2d: /* br3, beqc, bnec */
1155 func (stream
, "%s\t%s, %d, ", ((insn
& __BIT (19)) ? "bnec" : "beqc"),
1156 gpr_map
[rt
], __SEXT (__GF (insn
, 8, 11), 11));
1157 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
1159 case 0x32: /* misc */
1160 print_insn32_misc (pc
, info
, insn
);
1162 case 0x35: /* FPU */
1163 print_insn32_fpu (pc
, info
, insn
);
1169 print_insn_nds32 (bfd_vma pc
, disassemble_info
*info
)
1175 status
= info
->read_memory_func (pc
, (bfd_byte
*) buf
, 2, info
);
1179 /* 16-bit instruction. */
1182 insn
= bfd_getb16 (buf
);
1183 print_insn16 (pc
, info
, insn
);
1187 /* 32-bit instructions. */
1188 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) buf
+ 2, 2, info
);
1192 insn
= bfd_getb32 (buf
);
1193 print_insn32 (pc
, info
, insn
);