1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2014 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 /* Register name table. */
171 /* General purpose register. */
173 static const char *gpr_map
[] =
175 "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7",
176 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15",
177 "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23",
178 "$r24", "$r25", "$r26", "$r27", "$fp", "$gp", "$lp", "$sp"
181 /* User special register. */
183 static const char *usr_map
[][32] =
186 "d0.lo", "d0.hi", "d1.lo", "d1.hi", "4", "5", "6", "7",
187 "8", "9", "10", "11", "12", "13", "14", "15",
188 "16", "17", "18", "19", "20", "21", "22", "23",
189 "24", "25", "26", "27", "28", "29", "30", "pc"
192 "DMA_CFG", "DMA_GCSW", "DMA_CHNSEL", "DMA_ACT", "DMA_SETUP",
193 "DMA_ISADDR", "DMA_ESADDR", "DMA_TCNT", "DMA_STATUS", "DMA_2DSET",
194 "10", "11", "12", "13", "14",
195 "15", "16", "17", "18", "19",
196 "20", "21", "22", "23", "24",
200 "PFMC0", "PFMC1", "PFMC2", "3", "PFM_CTL"
204 /* System register. */
205 /* Major Minor Extension. */
206 static const char *sr_map
[8][16][8] =
209 {"CPU_VER", "CORE_ID"},
216 {"PSW", "IPSW", "P_IPSW"},
217 {"0", "IVB", "INT_CTRL"},
218 {"0", "EVA", "P_EVA"},
219 {"0", "ITYPE", "P_ITYPE"},
221 {"0", "IPC", "P_IPC", "OIPC"},
224 {"INT_MASK", "INT_MASK2"},
225 {"INT_PEND", "INT_PEND2", "2", "3", "INT_TRIGGER"},
226 {"SP_USR", "SP_PRIV"},
227 {"INT_PRI", "INT_PRI2"}
239 {"HSMP_SADDR", "HSMP_EADDR"},
245 {"SDZ_CTL", "MISC_CTL"}
248 {"BPC0", "BPC1", "BPC2", "BPC3", "BPC4", "BPC5", "BPC6", "BPC7"},
249 {"BPA0", "BPA1", "BPA2", "BPA3", "BPA4", "BPA5", "BPA6", "BPA7"},
250 {"BPAM0", "BPAM1", "BPAM2", "BPAM3", "BPAM4", "BPAM5", "BPAM6", "BPAM7"},
251 {"BPV0", "BPV1", "BPV2", "BPV3", "BPV4", "BPV5", "BPV6", "BPV7"},
252 {"BPCID0", "BPCID1", "BPCID2", "BPCID3", "BPCID4", "BPCID5", "BPCID6", "BPCID7"},
265 {"PFMC0", "PFMC1", "PFMC2"},
282 {"DMA_2DSET", "DMA_2DSCTL"}
287 print_insn16 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
)
289 static char r4map
[] =
291 0, 1, 2, 3, 4, 5, 6, 7,
292 8, 9, 10, 11, 16, 17, 18, 19
294 const int rt5
= __GF (insn
, 5, 5);
295 const int ra5
= __GF (insn
, 0, 5);
296 const int rt4
= r4map
[__GF (insn
, 5, 4)];
297 const int imm5u
= IMMU (insn
, 5);
298 const int imm9u
= IMMU (insn
, 9);
299 const int rt3
= __GF (insn
, 6, 3);
300 const int ra3
= __GF (insn
, 3, 3);
301 const int rb3
= __GF (insn
, 0, 3);
302 const int rt38
= __GF (insn
, 8, 3);
303 const int imm3u
= rb3
;
304 fprintf_ftype func
= info
->fprintf_func
;
305 void *stream
= info
->stream
;
307 static const char *mnemonic_96
[] =
309 "0x1", "0x1", "0x2", "0x3",
310 "add45", "sub45", "addi45", "subi45",
311 "srai45", "srli45", "slli333", "0xb",
312 "add333", "sub333", "addi333", "subi333",
313 "lwi333", "lwi333.bi", "lhi333", "lbi333",
314 "swi333", "swi333.bi", "shi333", "sbi333",
315 "addri36.sp", "lwi45.fe", "lwi450", "swi450",
316 "0x1c", "0x1d", "0x1e", "0x1f",
317 "0x20", "0x21", "0x22", "0x23",
318 "0x24", "0x25", "0x26", "0x27",
319 "0x28", "0x29", "0x2a", "0x2b",
320 "0x2c", "0x2d", "0x2e", "0x2f",
321 "slts45", "slt45", "sltsi45", "slti45",
322 "0x34", "0x35", "0x36", "0x37",
323 "0x38", "0x39", "0x3a", "0x3b",
327 static const char *mnemonic_misc33
[] =
329 "misc33_0", "misc33_1", "neg33", "not33", "mul33", "xor33", "and33", "or33",
332 static const char *mnemonic_0xb
[] =
334 "zeb33", "zeh33", "seb33", "seh33", "xlsb33", "x11b33", "bmski33", "fexti33"
337 static const char *mnemonic_bnes38
[] =
339 "jr5", "jral5", "ex9.it", "?", "ret5", "add5.pc"
342 switch (__GF (insn
, 7, 8))
344 case 0xf8: /* push25 */
345 case 0xf9: /* pop25 */
347 uint32_t res
[] = { 6, 8, 10, 14 };
348 uint32_t re
= res
[__GF (insn
, 5, 2)];
350 func (stream
, "%s\t%s, %d", (insn
& __BIT (7)) ? "pop25" : "push25",
351 gpr_map
[re
], imm5u
<< 3);
356 if (__GF (insn
, 8, 7) == 0x7d) /* movd44 */
358 int rt5e
= __GF (insn
, 4, 4) << 1;
359 int ra5e
= IMMU (insn
, 4) << 1;
361 func (stream
, "movd44\t%s, %d", gpr_map
[rt5e
], ra5e
);
365 switch (__GF (insn
, 9, 6))
367 case 0x4: /* add45 */
368 case 0x5: /* sub45 */
369 case 0x30: /* slts45 */
370 case 0x31: /* slt45 */
371 func (stream
, "%s\t%s, %s", mnemonic_96
[__GF (insn
, 9, 6)],
372 gpr_map
[rt4
], gpr_map
[ra5
]);
374 case 0x6: /* addi45 */
375 case 0x7: /* subi45 */
376 case 0x8: /* srai45 */
377 case 0x9: /* srli45 */
378 case 0x32: /* sltsi45 */
379 case 0x33: /* slti45 */
380 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
383 case 0xc: /* add333 */
384 case 0xd: /* sub333 */
385 func (stream
, "%s\t%s, %s, %s", mnemonic_96
[__GF (insn
, 9, 6)],
386 gpr_map
[rt3
], gpr_map
[ra3
], gpr_map
[rb3
]);
388 case 0xa: /* slli333 */
389 case 0xe: /* addi333 */
390 case 0xf: /* subi333 */
391 func (stream
, "%s\t%s, %s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
392 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
);
394 case 0x10: /* lwi333 */
395 case 0x14: /* swi333 */
396 func (stream
, "%s\t%s, [%s + %d]", mnemonic_96
[__GF (insn
, 9, 6)],
397 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
<< 2);
399 case 0x12: /* lhi333 */
400 case 0x16: /* shi333 */
401 func (stream
, "%s\t%s, [%s + %d]", mnemonic_96
[__GF (insn
, 9, 6)],
402 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
<< 1);
404 case 0x13: /* lbi333 */
405 case 0x17: /* sbi333 */
406 func (stream
, "%s\t%s, [%s + %d]", mnemonic_96
[__GF (insn
, 9, 6)],
407 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
);
409 case 0x11: /* lwi333.bi */
410 case 0x15: /* swi333.bi */
411 func (stream
, "%s\t%s, [%s], %d", mnemonic_96
[__GF (insn
, 9, 6)],
412 gpr_map
[rt3
], gpr_map
[ra3
], imm3u
<< 2);
414 case 0x18: /* addri36.sp */
415 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
416 gpr_map
[rt3
], IMMU (insn
, 6) << 2);
418 case 0x19: /* lwi45.fe */
419 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
420 gpr_map
[rt4
], -((32 - imm5u
) << 2));
422 case 0x1a: /* lwi450 */
423 case 0x1b: /* swi450 */
424 func (stream
, "%s\t%s, [%s]", mnemonic_96
[__GF (insn
, 9, 6)],
425 gpr_map
[rt4
], gpr_map
[ra5
]);
427 case 0x34: /* beqzs8, bnezs8 */
428 func (stream
, "%s\t", ((insn
& __BIT (8)) ? "bnezs8" : "beqzs8"));
429 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
431 case 0x35: /* break16, ex9.it */
432 /* FIXME: Check bfd_mach. */
433 if (imm9u
< 32) /* break16 */
434 func (stream
, "break16\t%d", imm9u
);
436 func (stream
, "ex9.it\t%d", imm9u
);
438 case 0x3c: /* ifcall9 */
439 func (stream
, "%s\t", mnemonic_96
[__GF (insn
, 9, 6)]);
440 info
->print_address_func ((IMMU (insn
, 9) << 1) + pc
, info
);
442 case 0x3d: /* movpi45 */
443 func (stream
, "%s\t%s, %d", mnemonic_96
[__GF (insn
, 9, 6)],
444 gpr_map
[rt4
], ra5
+ 16);
446 case 0x3f: /* MISC33 */
447 func (stream
, "%s\t%s, %s", mnemonic_misc33
[rb3
],
448 gpr_map
[rt3
], gpr_map
[ra3
]);
451 func (stream
, "%s\t%s, %s", mnemonic_0xb
[rb3
],
452 gpr_map
[rt3
], gpr_map
[ra3
]);
456 switch (__GF (insn
, 10, 5))
458 case 0x0: /* mov55 or ifret16 */
459 /* FIXME: Check bfd_mach. */
460 if (rt5
== ra5
&& rt5
== 31)
461 func (stream
, "ifret16");
463 func (stream
, "mov55\t%s, %s", gpr_map
[rt5
], gpr_map
[ra5
]);
465 case 0x1: /* movi55 */
466 func (stream
, "movi55\t%s, %d", gpr_map
[rt5
], IMMS (insn
, 5));
468 case 0x1b: /* addi10s (V2) */
469 func (stream
, "addi10s\t%d", IMMS (insn
, 10));
473 switch (__GF (insn
, 11, 4))
475 case 0x7: /* lwi37.fp/swi37.fp */
476 func (stream
, "%s\t%s, [$fp + 0x%x]",
477 ((insn
& __BIT (7)) ? "swi37" : "lwi37"),
478 gpr_map
[rt38
], IMMU (insn
, 7) << 2);
480 case 0x8: /* beqz38 */
481 case 0x9: /* bnez38 */
482 func (stream
, "%s\t%s, ",
483 ((__GF (insn
, 11, 4) & 1) ? "bnez38" : "beqz38"), gpr_map
[rt38
]);
484 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
486 case 0xa: /* beqs38/j8, implied r5 */
489 func (stream
, "j8\t");
490 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
494 func (stream
, "beqs38\t%s, ", gpr_map
[rt38
]);
495 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
498 case 0xb: /* bnes38 and others */
501 switch (__GF (insn
, 5, 3))
506 func (stream
, "%s\t%s", mnemonic_bnes38
[__GF (insn
, 5, 3)],
509 case 2: /* ex9.it imm5 */
510 case 5: /* add5.pc */
511 func (stream
, "%s\t%d", mnemonic_bnes38
[__GF (insn
, 5, 3)], ra5
);
514 func (stream
, UNKNOWN_INSN_MSG
);
520 func (stream
, "bnes38\t%s", gpr_map
[rt3
]);
521 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
524 case 0xe: /* lwi37/swi37 */
525 func (stream
, "%s\t%s, [+ 0x%x]",
526 ((insn
& __BIT (7)) ? "swi37.sp" : "lwi37.sp"),
527 gpr_map
[rt38
], IMMU (insn
, 7) << 2);
534 print_insn32_mem (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
,
537 const int rt
= RT5 (insn
);
538 const int ra
= RA5 (insn
);
539 const int rb
= RB5 (insn
);
540 const int sv
= __GF (insn
, 8, 2);
541 const int op
= insn
& 0xFF;
542 fprintf_ftype func
= info
->fprintf_func
;
543 void *stream
= info
->stream
;
560 case 0x20: /* lbup */
561 case 0x22: /* lwup */
562 case 0x28: /* sbup */
563 case 0x2a: /* swup */
564 func (stream
, "%s\t%s, [%s + (%s << %d)]",
565 mnemonic_mem
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], sv
);
567 case 0x4: /* lb.bi */
568 case 0x5: /* lh.bi */
569 case 0x6: /* lw.bi */
570 case 0x7: /* ld.bi */
571 case 0xc: /* sb.bi */
572 case 0xd: /* sh.bi */
573 case 0xe: /* sw.bi */
574 case 0xf: /* sd.bi */
575 case 0x14: /* lbs.bi */
576 case 0x15: /* lhs.bi */
577 case 0x16: /* lws.bi */
578 func (stream
, "%s\t%s, [%s], (%s << %d)",
579 mnemonic_mem
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], sv
);
581 case 0x13: /* dpref */
583 const char *subtype
= "???";
585 if ((rt
& 0xf) < ARRAY_SIZE (keyword_dpref
))
586 subtype
= keyword_dpref
[rt
& 0xf];
588 func (stream
, "%s\t%s, [%s + (%s << %d)]",
589 "dpref", subtype
, gpr_map
[ra
], gpr_map
[rb
], sv
);
593 func (stream
, UNKNOWN_INSN_MSG
);
599 print_insn32_alu1 (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
, uint32_t insn
)
601 int op
= insn
& 0x1f;
602 const int rt
= RT5 (insn
);
603 const int ra
= RA5 (insn
);
604 const int rb
= RB5 (insn
);
605 const int rd
= RD5 (insn
);
606 fprintf_ftype func
= info
->fprintf_func
;
607 void *stream
= info
->stream
;
611 case 0x0: /* add, add_slli */
612 case 0x1: /* sub, sub_slli */
613 case 0x2: /* and, add_slli */
614 case 0x3: /* xor, xor_slli */
615 case 0x4: /* or, or_slli */
618 func (stream
, "%s_slli\t%s, %s, %s, #%d",
619 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], rd
);
623 func (stream
, "%s\t%s, %s, %s",
624 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
627 case 0x1c: /* add_srli */
628 case 0x1d: /* sub_srli */
629 case 0x1e: /* and_srli */
630 case 0x1f: /* xor_srli */
631 case 0x15: /* or_srli */
632 func (stream
, "%s\t%s, %s, %s, #%d",
633 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
], rd
);
642 case 0x12: /* bitc */
645 case 0x1a: /* cmovz */
646 case 0x1b: /* cmovn */
647 func (stream
, "%s\t%s, %s, %s",
648 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
651 if (ra
==0 && rb
== 0 && rb
==0)
653 func (stream
, "nop");
658 case 0xb: /* rotri */
659 func (stream
, "%s\t%s, %s, #%d",
660 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
], rb
);
665 case 0x14: /* wsbh */
666 func (stream
, "%s\t%s, %s",
667 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[ra
]);
669 case 0x16: /* divsr */
670 case 0x17: /* divr */
671 func (stream
, "%s\t%s, %s, %s, %s",
672 mnemonic_alu1
[op
], gpr_map
[rt
], gpr_map
[rd
], gpr_map
[ra
], gpr_map
[rb
]);
675 func (stream
, UNKNOWN_INSN_MSG
);
683 print_insn32_alu2 (bfd_vma pc ATTRIBUTE_UNUSED
,
684 disassemble_info
*info
,
687 int op
= insn
& 0x3ff;
688 const int rt
= RT5 (insn
);
689 const int ra
= RA5 (insn
);
690 const int rb
= RB5 (insn
);
691 fprintf_ftype func
= info
->fprintf_func
;
692 void *stream
= info
->stream
;
694 if ((insn
& 0x7f) == 0x4e) /* ffbi */
696 func (stream
, "ffbi\t%s, %s, #0x%x",
697 gpr_map
[rt
], gpr_map
[ra
], __GF (insn
, 7, 8));
709 case 0xf: /* ffmism */
710 case 0x17: /* ffzmism */
712 func (stream
, "%s\t%s, %s, %s", mnemonic_alu20
[op
],
713 gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
719 func (stream
, "%s\t%s, %s", mnemonic_alu20
[op
], gpr_map
[rt
], gpr_map
[ra
]);
722 case 0x4: /* clips */
728 func (stream
, "%s\t%s, %s, #%d", mnemonic_alu20
[op
],
729 gpr_map
[rt
], gpr_map
[ra
], IMM1U (insn
));
732 case 0x20: /* mfusr */
733 case 0x21: /* mtusr */
734 func (stream
, "%s\t%s, $%s", mnemonic_alu20
[op
],
735 gpr_map
[rt
], usr_map
[__GF (insn
, 10, 5)][__GF (insn
, 15, 5)]);
737 case 0x28: /* mults64 */
738 case 0x29: /* mult64 */
739 case 0x2a: /* madds64 */
740 case 0x2b: /* madd64 */
741 case 0x2c: /* msubs64 */
742 case 0x2d: /* msub64 */
743 case 0x2e: /* divs */
745 case 0x31: /* mult32 */
746 case 0x33: /* madd32 */
747 case 0x35: /* msub32 */
748 func (stream
, "%s\t$d%d, %s, %s", mnemonic_alu20
[op
],
749 rt
>> 1, gpr_map
[ra
], gpr_map
[rb
]);
752 case 0x4f: /* flmism */
753 case 0x68: /* mulsr64 */
754 case 0x69: /* mulr64 */
755 case 0x73: /* maddr32 */
756 case 0x75: /* msubr32 */
758 func (stream
, "%s\t%s, %s, %s", mnemonic_alu21
[op
],
759 gpr_map
[rt
], gpr_map
[ra
], gpr_map
[rb
]);
762 func (stream
, UNKNOWN_INSN_MSG
);
768 print_insn32_jreg (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
, uint32_t insn
)
770 int op
= insn
& 0xff;
771 const int rt
= RT5 (insn
);
772 const int rb
= RB5 (insn
);
773 const char *dtit_on
[] = { "", ".iton", ".dton", ".ton" };
774 const char *dtit_off
[] = { "", ".itoff", ".dtoff", ".toff" };
775 const char *mnemonic_jreg
[] = { "jr", "jral", "jrnez", "jralnez" };
776 const char *mnemonic_ret
[] = { "jr", "ret", NULL
, "ifret" };
777 const int dtit
= __GF (insn
, 8, 2);
778 fprintf_ftype func
= info
->fprintf_func
;
779 void *stream
= info
->stream
;
784 func (stream
, "%s%s\t%s", mnemonic_ret
[op
>> 5],
785 dtit_on
[dtit
], gpr_map
[rb
]);
789 func (stream
, "%s%s\t%s", mnemonic_ret
[op
>> 5],
790 dtit_off
[dtit
], gpr_map
[rb
]);
792 case 0x60: /* ifret */
796 case 3: /* jralnez */
797 func (stream
, "%s%s\t%s, %s", mnemonic_jreg
[op
],
798 dtit_on
[dtit
], gpr_map
[rt
], gpr_map
[rb
]);
800 default: /* unknown */
801 func (stream
, UNKNOWN_INSN_MSG
);
807 print_insn32_misc (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
,
810 int op
= insn
& 0x1f;
813 fprintf_ftype func
= info
->fprintf_func
;
814 void *stream
= info
->stream
;
816 static const char *keyword_standby
[] =
818 "no_wake_grant", "wake_grant", "wait_done",
820 static const char *keyword_tlbop
[] =
822 "TRD", "TWR", "RWR", "RWLK", "UNLK", "PB", "INV", "FLUA"
827 case 0x0: /* standby */
828 id
= __GF (insn
, 5, 20);
829 if (id
< ARRAY_SIZE (keyword_standby
))
830 func (stream
, "standby\t%s", keyword_standby
[id
]);
832 func (stream
, "standby\t%d", id
);
835 func (stream
, "cctl\t!FIXME");
839 case 0xd: /* isync */
840 case 0xc: /* msync */
842 func (stream
, "%s", mnemonic_misc
[op
]);
845 case 0xa: /* break */
846 case 0xb: /* syscall */
847 id
= __GF (insn
, 5, 15);
848 func (stream
, "%s\t%d", mnemonic_misc
[op
], id
);
852 /* FIXME: setend, setgie. */
853 func (stream
, "%s\t%s, $%s", mnemonic_misc
[op
], gpr_map
[rt
],
854 sr_map
[__GF(insn
, 17, 3)][__GF(insn
, 13, 4)][__GF(insn
, 10, 3)]);
858 id
= __GF (insn
, 5, 15);
859 func (stream
, "%s\t%s, %d", mnemonic_misc
[op
], gpr_map
[rt
], id
);
861 case 0xe: /* tlbop */
862 id
= __GF (insn
, 5, 5);
863 if (id
< ARRAY_SIZE (keyword_tlbop
))
864 func (stream
, "tlbop\t%s", keyword_tlbop
[id
]);
866 func (stream
, "tlbop\t%d", id
);
872 print_insn32_fpu (bfd_vma pc ATTRIBUTE_UNUSED
, disassemble_info
*info
,
876 int mask_sub_op
= (insn
& 0x3c0) >> 6;
877 int mask_bi
= (insn
& 0x80) >> 7;
878 int mask_cfg
= (insn
& 0x7c00) >> 10;
879 int mask_f2op
= (insn
& 0x7c00) >> 10;
883 const int rt
= RT5 (insn
);
884 const int ra
= RA5 (insn
);
885 const int rb
= RB5 (insn
);
886 const int sv
= __GF (insn
, 8, 2);
887 fprintf_ftype func
= info
->fprintf_func
;
888 void *stream
= info
->stream
;
894 dp
= (op
& 0x8) ? 1 : 0;
917 func (stream
, "%s\t$f%c%d, $f%c%d, $f%c%d",
918 mnemonic_alu
[mask_sub_op
+ dp_insn
],
919 wd
, rt
, wd
, ra
, wd
, rb
);
923 func (stream
, "%s\t$f%c%d, $f%c%d, $fs%d",
924 mnemonic_alu
[mask_sub_op
+ dp_insn
],
943 func (stream
, "%s\t$fs%d, $fd%d",
944 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], rt
, ra
);
946 func (stream
, "%s\t$fd%d, $fs%d",
947 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], rt
, ra
);
951 func (stream
, "%s\t$f%c%d, $f%c%d",
952 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], wd
, rt
, wd
, ra
);
956 func (stream
, "%s\t$f%c%d, $fs%d",
957 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], wd
, rt
, ra
);
963 func (stream
, "%s\t$fs%d, $f%c%d",
964 mnemonic_fpu_2op
[mask_f2op
+ dp_insn
], rt
, wd
, ra
);
972 func (stream
, "fmfsr\t%s, $fs%d", gpr_map
[rt
], ra
);
975 func (stream
, "fmfdr\t%s, $fd%d", gpr_map
[rt
], ra
);
979 func (stream
, "fmfcsr\t%s", gpr_map
[rt
]);
981 func (stream
, "fmfcfg\t%s", gpr_map
[rt
]);
986 func (stream
, "fls.bi\t$fs%d, [%s], (%s << %d)",
987 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
989 func (stream
, "fls\t$fs%d, [%s + (%s << %d)]",
990 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
994 func (stream
, "fld.bi\t$fd%d, [%s], (%s << %d)",
995 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
997 func (stream
, "fld\t$fd%d, [%s + (%s << %d)]",
998 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
1001 func (stream
, "%s\t$fs%d, $fs%d, $fs%d",
1002 mnemonic_fs2_cmp
[mask_sub_op
], rt
, ra
, rb
);
1004 case 0x9: /* mtcp */
1005 switch (mask_sub_op
)
1008 func (stream
, "fmtsr\t%s, $fs%d", gpr_map
[rt
], ra
);
1011 func (stream
, "fmtdr\t%s, $fd%d", gpr_map
[rt
], ra
);
1014 func (stream
, "fmtcsr\t%s", gpr_map
[rt
]);
1019 func (stream
, "fss.bi\t$fs%d, [%s], (%s << %d)",
1020 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
1022 func (stream
, "fss\t$fs%d, [%s + (%s << %d)]",
1023 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
1027 func (stream
, "fsd.bi\t$fd%d, [%s], (%s << %d)",
1028 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
1030 func (stream
, "fsd\t$fd%d, [%s + (%s << %d)]",
1031 rt
, gpr_map
[ra
], gpr_map
[rb
], sv
);
1034 func (stream
, "%s\t$fs%d, $fd%d, $fd%d",
1035 mnemonic_fd2_cmp
[mask_sub_op
], rt
, ra
, rb
);
1041 print_insn32 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
)
1043 int op
= OP6 (insn
);
1044 const int rt
= RT5 (insn
);
1045 const int ra
= RA5 (insn
);
1046 const int rb
= RB5 (insn
);
1047 const int imm15s
= IMMS (insn
, 15);
1048 const int imm15u
= IMMU (insn
, 15);
1050 fprintf_ftype func
= info
->fprintf_func
;
1051 void *stream
= info
->stream
;
1063 case 0x10: /* lbsi */
1064 case 0x11: /* lhsi */
1065 case 0x12: /* lwsi */
1067 func (stream
, "%s\t%s, [%s + #%d]",
1068 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15s
<< shift
);
1070 case 0x4: /* lbi.bi */
1071 case 0x5: /* lhi.bi */
1072 case 0x6: /* lwi.bi */
1073 case 0x7: /* ldi.bi */
1074 case 0xc: /* sbi.bi */
1075 case 0xd: /* shi.bi */
1076 case 0xe: /* swi.bi */
1077 case 0xf: /* sdi.bi */
1078 case 0x14: /* lbsi.bi */
1079 case 0x15: /* lhsi.bi */
1080 case 0x16: /* lwsi.bi */
1082 func (stream
, "%s\t%s, [%s], #%d",
1083 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15s
<< shift
);
1085 case 0x13: /* dprefi */
1087 const char *subtype
= "???";
1099 if ((rt
& 0xf) < ARRAY_SIZE (keyword_dpref
))
1100 subtype
= keyword_dpref
[rt
& 0xf];
1102 func (stream
, "%s.%c\t%s, [%s + #%d]",
1103 mnemonic_op6
[op
], wd
, subtype
, gpr_map
[ra
], imm15s
<< shift
);
1106 case 0x17: /* LBGP */
1107 func (stream
, "%s\t%s, [+ %d]",
1108 ((insn
& __BIT (19)) ? "lbsi.gp" : "lbi.gp"),
1109 gpr_map
[rt
], IMMS (insn
, 19));
1111 case 0x18: /* LWC */
1112 case 0x19: /* SWC */
1113 case 0x1a: /* LDC */
1114 case 0x1b: /* SDC */
1115 if (__GF (insn
, 13, 2) == 0)
1117 char ls
= (op
& 1) ? 's' : 'l';
1118 char wd
= (op
& 2) ? 'd' : 's';
1120 if (insn
& __BIT (12))
1122 func (stream
, "f%c%ci.bi\t$f%c%d, [%s], %d", ls
, wd
,
1123 wd
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1127 func (stream
, "f%c%ci\t$f%c%d, [%s + %d]", ls
, wd
,
1128 wd
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1133 char ls
= (op
& 1) ? 's' : 'l';
1134 char wd
= (op
& 2) ? 'd' : 'w';
1135 int cp
= __GF (insn
, 13, 2);
1137 if (insn
& __BIT (12))
1139 func (stream
, "cp%c%ci\tcp%d, $cpr%d, [%s], %d", ls
, wd
,
1140 cp
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1144 func (stream
, "cp%c%ci\tcp%d, $cpr%d, [%s + %d]", ls
, wd
,
1145 cp
, rt
, gpr_map
[ra
], IMMS (insn
, 12) << 2);
1149 case 0x1c: /* MEM */
1150 print_insn32_mem (pc
, info
, insn
);
1152 case 0x1d: /* LSMW */
1154 int enb4
= __GF (insn
, 6, 4);
1155 char ls
= (insn
& __BIT (5)) ? 's' : 'l';
1156 char ab
= (insn
& __BIT (4)) ? 'a' : 'b';
1157 char *di
= (insn
& __BIT (3)) ? "d" : "i";
1158 char *m
= (insn
& __BIT (2)) ? "m" : "";
1159 static const char *s
[] = {"", "a", "zb", "?"};
1161 /* lsmwzb only always increase. */
1162 if ((insn
& 0x3) == 2)
1165 func (stream
, "%cmw%s.%c%s%s\t%s, [%s], %s, 0x%x",
1166 ls
, s
[insn
& 0x3], ab
, di
, m
, gpr_map
[rt
],
1167 gpr_map
[ra
], gpr_map
[rb
], enb4
);
1170 case 0x1e: /* HWGP */
1171 op
= __GF (insn
, 17, 3);
1174 case 0: case 1: /* lhi.gp */
1175 case 2: case 3: /* lhsi.gp */
1176 case 4: case 5: /* shi.gp */
1177 func (stream
, "%s\t%s, [+ %d]",
1178 mnemonic_hwgp
[op
], gpr_map
[rt
], IMMS (insn
, 18) << 1);
1180 case 6: /* lwi.gp */
1181 case 7: /* swi.gp */
1182 func (stream
, "%s\t%s, [+ %d]",
1183 mnemonic_hwgp
[op
], gpr_map
[rt
], IMMS (insn
, 17) << 2);
1187 case 0x1f: /* SBGP */
1188 if (insn
& __BIT (19))
1189 func (stream
, "addi.gp\t%s, %d",
1190 gpr_map
[rt
], IMMS (insn
, 19));
1192 func (stream
, "sbi.gp\t%s, [+ %d]",
1193 gpr_map
[rt
], IMMS (insn
, 19));
1195 case 0x20: /* ALU_1 */
1196 print_insn32_alu1 (pc
, info
, insn
);
1198 case 0x21: /* ALU_2 */
1199 print_insn32_alu2 (pc
, info
, insn
);
1201 case 0x22: /* movi */
1202 func (stream
, "movi\t%s, %d", gpr_map
[rt
], IMMS (insn
, 20));
1204 case 0x23: /* sethi */
1205 func (stream
, "sethi\t%s, 0x%x", gpr_map
[rt
], IMMU (insn
, 20));
1207 case 0x24: /* ji, jal */
1208 /* FIXME: Handle relocation. */
1209 if (info
->flags
& INSN_HAS_RELOC
)
1211 func (stream
, "%s\t", ((insn
& __BIT (24)) ? "jal" : "j"));
1212 info
->print_address_func ((IMMS (insn
, 24) << 1) + pc
, info
);
1214 case 0x25: /* jreg */
1215 print_insn32_jreg (pc
, info
, insn
);
1217 case 0x26: /* br1 */
1218 func (stream
, "%s\t%s, %s, ", ((insn
& __BIT (14)) ? "bne" : "beq"),
1219 gpr_map
[rt
], gpr_map
[ra
]);
1220 info
->print_address_func ((IMMS (insn
, 14) << 1) + pc
, info
);
1222 case 0x27: /* br2 */
1223 func (stream
, "%s\t%s, ", mnemonic_br2
[__GF (insn
, 16, 4)],
1225 info
->print_address_func ((IMMS (insn
, 16) << 1) + pc
, info
);
1227 case 0x28: /* addi */
1228 case 0x2e: /* slti */
1229 case 0x2f: /* sltsi */
1230 case 0x29: /* subri */
1231 func (stream
, "%s\t%s, %s, %d",
1232 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15s
);
1234 case 0x2a: /* andi */
1235 case 0x2b: /* xori */
1236 case 0x2c: /* ori */
1237 case 0x33: /* bitci */
1238 func (stream
, "%s\t%s, %s, %d",
1239 mnemonic_op6
[op
], gpr_map
[rt
], gpr_map
[ra
], imm15u
);
1241 case 0x2d: /* br3, beqc, bnec */
1242 func (stream
, "%s\t%s, %d, ", ((insn
& __BIT (19)) ? "bnec" : "beqc"),
1243 gpr_map
[rt
], __SEXT (__GF (insn
, 8, 11), 11));
1244 info
->print_address_func ((IMMS (insn
, 8) << 1) + pc
, info
);
1246 case 0x32: /* misc */
1247 print_insn32_misc (pc
, info
, insn
);
1249 case 0x35: /* FPU */
1250 print_insn32_fpu (pc
, info
, insn
);
1256 print_insn_nds32 (bfd_vma pc
, disassemble_info
*info
)
1262 status
= info
->read_memory_func (pc
, (bfd_byte
*) buf
, 2, info
);
1266 /* 16-bit instruction. */
1269 insn
= bfd_getb16 (buf
);
1270 print_insn16 (pc
, info
, insn
);
1274 /* 32-bit instructions. */
1275 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) buf
+ 2, 2, info
);
1279 insn
= bfd_getb32 (buf
);
1280 print_insn32 (pc
, info
, insn
);