]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/nds32-dis.c
c732e841c09a7fac6145462c5adf804be9b9f6b3
[thirdparty/binutils-gdb.git] / opcodes / nds32-dis.c
1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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
20 02110-1301, USA.*/
21
22
23 #include "sysdep.h"
24 #include <stdio.h>
25 #include "ansidecl.h"
26 #include "dis-asm.h"
27 #include "bfd.h"
28 #include "symcat.h"
29 #include "libiberty.h"
30 #include "opintl.h"
31 #include "bfd_stdint.h"
32
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)
39
40 /* Get fields */
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)
54
55 /* Default text to print if an instruction isn't recognized. */
56 #define UNKNOWN_INSN_MSG _("*unknown*")
57
58 static const char *mnemonic_op6[] =
59 {
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"
67 };
68
69 static const char *mnemonic_mem[] =
70 {
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",
76 "sbup", "51", "swup"
77 };
78
79 static const char *mnemonic_alu1[] =
80 {
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"
85 };
86
87
88 static const char *mnemonic_alu20[] =
89 {
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"
98 };
99
100 static const char *mnemonic_alu21[] =
101 {
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"
110 };
111
112 static const char *mnemonic_br2[] =
113 {
114 "ifcall", "01", "beqz", "bnez", "bgez", "bltz", "bgtz", "blez",
115 "10", "11", "12", "13", "bgezal", "bltzal"
116 };
117
118 static const char *mnemonic_misc[] =
119 {
120 "standby", "cctl", "mfsr", "mtsr", "iret", "trap", "teqz", "tnez",
121 "dsb", "isb", "break", "syscall", "msync", "isync", "tlbop"
122 };
123
124 static const char *mnemonic_hwgp[] =
125 {
126 "lhi.gp", "lhi.gp", "lhsi.gp", "lhsi.gp",
127 "shi.gp", "shi.gp", "lwi.gp", "swi.gp"
128 };
129
130 static const char *keyword_dpref[] =
131 {
132 "SRD", "MRD", "SWR", "MWR", "PTE", "CLWR", "6", "7",
133 "8", "9", "10", "11", "12", "13", "14", "15"
134 };
135
136 static const char *mnemonic_alu[] =
137 {
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"
144 };
145
146 static const char *mnemonic_fpu_2op[] =
147 {
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",
155 "56", "fd2si.z"
156 };
157
158 static const char *mnemonic_fs2_cmp[] =
159 {
160 "fcmpeqs", "fcmpeqs.e", "fcmplts", "fcmplts.e",
161 "fcmples", "fcmples.e", "fcmpuns", "fcmpuns.e"
162 };
163
164 static const char *mnemonic_fd2_cmp[] =
165 {
166 "fcmpeqd", "fcmpeqd.e", "fcmpltd", "fcmpltd.e",
167 "fcmpled", "fcmpled.e", "fcmpund", "fcmpund.e"
168 };
169
170 /* Register name table. */
171 /* General purpose register. */
172
173 static const char *gpr_map[] =
174 {
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"
179 };
180
181 /* User special register. */
182
183 static const char *usr_map[][32] =
184 {
185 {
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"
190 },
191 {
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",
197 "DMA_2DSCTL"
198 },
199 {
200 "PFMC0", "PFMC1", "PFMC2", "3", "PFM_CTL"
201 }
202 };
203
204 /* System register. */
205 /* Major Minor Extension. */
206 static const char *sr_map[8][16][8] =
207 {
208 {
209 {"CPU_VER", "CORE_ID"},
210 {"ICM_CFG"},
211 {"DCM_CFG"},
212 {"MMU_CFG"},
213 {"MSC_CFG"}
214 },
215 {
216 {"PSW", "IPSW", "P_IPSW"},
217 {"0", "IVB", "INT_CTRL"},
218 {"0", "EVA", "P_EVA"},
219 {"0", "ITYPE", "P_ITYPE"},
220 {"0", "MERR"},
221 {"0", "IPC", "P_IPC", "OIPC"},
222 {"0", "1", "P_P0"},
223 {"0", "1", "P_P1"},
224 {"INT_MASK", "INT_MASK2"},
225 {"INT_PEND", "INT_PEND2", "2", "3", "INT_TRIGGER"},
226 {"SP_USR", "SP_PRIV"},
227 {"INT_PRI", "INT_PRI2"}
228 },
229 {
230 {"MMU_CTL"},
231 {"L1_PPTB"},
232 {"TLB_VPN"},
233 {"TLB_DATA"},
234 {"TLB_MISC"},
235 {"VLPT_IDX"},
236 {"ILMB"},
237 {"DLMB"},
238 {"CACHE_CTL"},
239 {"HSMP_SADDR", "HSMP_EADDR"},
240 {"0"},
241 {"0"},
242 {"0"},
243 {"0"},
244 {"0"},
245 {"SDZ_CTL", "MISC_CTL"}
246 },
247 {
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"},
253 {"EDM_CFG"},
254 {"EDMSW"},
255 {"EDM_CTL"},
256 {"EDM_DTR"},
257 {"BPMTC"},
258 {"DIMBR"},
259 {"EDM_PROBE"},
260 {"0"},
261 {"0"},
262 {"TECR0", "TECR1"}
263 },
264 {
265 {"PFMC0", "PFMC1", "PFMC2"},
266 {"PFM_CTL"},
267 {"0"},
268 {"0"},
269 {"PRUSR_ACC_CTL"},
270 {"FUCOP_CTL"}
271 },
272 {
273 {"DMA_CFG"},
274 {"DMA_GCSW"},
275 {"DMA_CHNSEL"},
276 {"DMA_ACT"},
277 {"DMA_SETUP"},
278 {"DMA_ISADDR"},
279 {"DMA_ESADDR"},
280 {"DMA_TCNT"},
281 {"DMA_STATUS"},
282 {"DMA_2DSET", "DMA_2DSCTL"}
283 }
284 };
285
286 static void
287 print_insn16 (bfd_vma pc, disassemble_info *info, uint32_t insn)
288 {
289 static char r4map[] =
290 {
291 0, 1, 2, 3, 4, 5, 6, 7,
292 8, 9, 10, 11, 16, 17, 18, 19
293 };
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;
306
307 static const char *mnemonic_96[] =
308 {
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",
324 "ifcall9", "movpi45"
325 };
326
327 static const char *mnemonic_misc33[] =
328 {
329 "misc33_0", "misc33_1", "neg33", "not33", "mul33", "xor33", "and33", "or33",
330 };
331
332 static const char *mnemonic_0xb[] =
333 {
334 "zeb33", "zeh33", "seb33", "seh33", "xlsb33", "x11b33", "bmski33", "fexti33"
335 };
336
337 static const char *mnemonic_bnes38[] =
338 {
339 "jr5", "jral5", "ex9.it", "?", "ret5", "add5.pc"
340 };
341
342 switch (__GF (insn, 7, 8))
343 {
344 case 0xf8: /* push25 */
345 case 0xf9: /* pop25 */
346 {
347 uint32_t res[] = { 6, 8, 10, 14 };
348 uint32_t re = res[__GF (insn, 5, 2)];
349
350 func (stream, "%s\t%s, %d", (insn & __BIT (7)) ? "pop25" : "push25",
351 gpr_map[re], imm5u << 3);
352 }
353 return;
354 }
355
356 if (__GF (insn, 8, 7) == 0x7d) /* movd44 */
357 {
358 int rt5e = __GF (insn, 4, 4) << 1;
359 int ra5e = IMMU (insn, 4) << 1;
360
361 func (stream, "movd44\t%s, %d", gpr_map[rt5e], ra5e);
362 return;
363 }
364
365 switch (__GF (insn, 9, 6))
366 {
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]);
373 return;
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)],
381 gpr_map[rt4], ra5);
382 return;
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]);
387 return;
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);
393 return;
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);
398 return;
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);
403 return;
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);
408 return;
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);
413 return;
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);
417 return;
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));
421 return;
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]);
426 return;
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);
430 return;
431 case 0x35: /* break16, ex9.it */
432 /* FIXME: Check bfd_mach. */
433 if (imm9u < 32) /* break16 */
434 func (stream, "break16\t%d", imm9u);
435 else
436 func (stream, "ex9.it\t%d", imm9u);
437 return;
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);
441 return;
442 case 0x3d: /* movpi45 */
443 func (stream, "%s\t%s, %d", mnemonic_96[__GF (insn, 9, 6)],
444 gpr_map[rt4], ra5 + 16);
445 return;
446 case 0x3f: /* MISC33 */
447 func (stream, "%s\t%s, %s", mnemonic_misc33[rb3],
448 gpr_map[rt3], gpr_map[ra3]);
449 return;
450 case 0xb: /* ... */
451 func (stream, "%s\t%s, %s", mnemonic_0xb[rb3],
452 gpr_map[rt3], gpr_map[ra3]);
453 return;
454 }
455
456 switch (__GF (insn, 10, 5))
457 {
458 case 0x0: /* mov55 or ifret16 */
459 /* FIXME: Check bfd_mach. */
460 if (rt5 == ra5 && rt5 == 31)
461 func (stream, "ifret16");
462 else
463 func (stream, "mov55\t%s, %s", gpr_map[rt5], gpr_map[ra5]);
464 return;
465 case 0x1: /* movi55 */
466 func (stream, "movi55\t%s, %d", gpr_map[rt5], IMMS (insn, 5));
467 return;
468 case 0x1b: /* addi10s (V2) */
469 func (stream, "addi10s\t%d", IMMS (insn, 10));
470 return;
471 }
472
473 switch (__GF (insn, 11, 4))
474 {
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);
479 return;
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);
485 return;
486 case 0xa: /* beqs38/j8, implied r5 */
487 if (rt38 == 5)
488 {
489 func (stream, "j8\t");
490 info->print_address_func ((IMMS (insn, 8) << 1) + pc, info);
491 }
492 else
493 {
494 func (stream, "beqs38\t%s, ", gpr_map[rt38]);
495 info->print_address_func ((IMMS (insn, 8) << 1) + pc, info);
496 }
497 return;
498 case 0xb: /* bnes38 and others */
499 if (rt38 == 5)
500 {
501 switch (__GF (insn, 5, 3))
502 {
503 case 0: /* jr5 */
504 case 1: /* jral5 */
505 case 4: /* ret5 */
506 func (stream, "%s\t%s", mnemonic_bnes38[__GF (insn, 5, 3)],
507 gpr_map[ra5]);
508 return;
509 case 2: /* ex9.it imm5 */
510 case 5: /* add5.pc */
511 func (stream, "%s\t%d", mnemonic_bnes38[__GF (insn, 5, 3)], ra5);
512 return;
513 default:
514 func (stream, UNKNOWN_INSN_MSG);
515 return;
516 }
517 }
518 else
519 {
520 func (stream, "bnes38\t%s", gpr_map[rt3]);
521 info->print_address_func ((IMMS (insn, 8) << 1) + pc, info);
522 }
523 return;
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);
528 return;
529 }
530 }
531
532
533 static void
534 print_insn32_mem (bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info,
535 uint32_t insn)
536 {
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;
544
545 switch (op)
546 {
547 case 0x0: /* lb */
548 case 0x1: /* lh */
549 case 0x2: /* lw */
550 case 0x3: /* ld */
551 case 0x8: /* sb */
552 case 0x9: /* sh */
553 case 0xa: /* sw */
554 case 0xb: /* sd */
555 case 0x10: /* lbs */
556 case 0x11: /* lhs */
557 case 0x12: /* lws */
558 case 0x18: /* llw */
559 case 0x19: /* scw */
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);
566 break;
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);
580 break;
581 case 0x13: /* dpref */
582 {
583 const char *subtype = "???";
584
585 if ((rt & 0xf) < ARRAY_SIZE (keyword_dpref))
586 subtype = keyword_dpref[rt & 0xf];
587
588 func (stream, "%s\t%s, [%s + (%s << %d)]",
589 "dpref", subtype, gpr_map[ra], gpr_map[rb], sv);
590 }
591 break;
592 default:
593 func (stream, UNKNOWN_INSN_MSG);
594 return;
595 }
596 }
597
598 static void
599 print_insn32_alu1 (bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info, uint32_t insn)
600 {
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;
608
609 switch (op)
610 {
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 */
616 if (rd != 0)
617 {
618 func (stream, "%s_slli\t%s, %s, %s, #%d",
619 mnemonic_alu1[op], gpr_map[rt], gpr_map[ra], gpr_map[rb], rd);
620 }
621 else
622 {
623 func (stream, "%s\t%s, %s, %s",
624 mnemonic_alu1[op], gpr_map[rt], gpr_map[ra], gpr_map[rb]);
625 }
626 return;
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);
634 return;
635 case 0x5: /* nor */
636 case 0x6: /* slt */
637 case 0x7: /* slts */
638 case 0xc: /* sll */
639 case 0xd: /* srl */
640 case 0xe: /* sra */
641 case 0xf: /* rotr */
642 case 0x12: /* bitc */
643 case 0x18: /* sva */
644 case 0x19: /* svs */
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]);
649 return;
650 case 0x9: /* srli */
651 if (ra ==0 && rb == 0 && rb==0)
652 {
653 func (stream, "nop");
654 return;
655 }
656 case 0x8: /* slli */
657 case 0xa: /* srai */
658 case 0xb: /* rotri */
659 func (stream, "%s\t%s, %s, #%d",
660 mnemonic_alu1[op], gpr_map[rt], gpr_map[ra], rb);
661 return;
662 case 0x10: /* seb */
663 case 0x11: /* seh */
664 case 0x13: /* zeh */
665 case 0x14: /* wsbh */
666 func (stream, "%s\t%s, %s",
667 mnemonic_alu1[op], gpr_map[rt], gpr_map[ra]);
668 return;
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]);
673 return;
674 default:
675 func (stream, UNKNOWN_INSN_MSG);
676 return;
677 }
678
679 return;
680 }
681
682 static void
683 print_insn32_alu2 (bfd_vma pc ATTRIBUTE_UNUSED,
684 disassemble_info *info,
685 uint32_t insn)
686 {
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;
693
694 if ((insn & 0x7f) == 0x4e) /* ffbi */
695 {
696 func (stream, "ffbi\t%s, %s, #0x%x",
697 gpr_map[rt], gpr_map[ra], __GF (insn, 7, 8));
698 return;
699 }
700
701 switch (op)
702 {
703 case 0x0: /* max */
704 case 0x1: /* min */
705 case 0x2: /* ave */
706 case 0xc: /* bse */
707 case 0xd: /* bsp */
708 case 0xe: /* ffb */
709 case 0xf: /* ffmism */
710 case 0x17: /* ffzmism */
711 case 0x24: /* mul */
712 func (stream, "%s\t%s, %s, %s", mnemonic_alu20[op],
713 gpr_map[rt], gpr_map[ra], gpr_map[rb]);
714 return;
715
716 case 0x3: /* abs */
717 case 0x6: /* clo */
718 case 0x7: /* clz */
719 func (stream, "%s\t%s, %s", mnemonic_alu20[op], gpr_map[rt], gpr_map[ra]);
720 return;
721
722 case 0x4: /* clips */
723 case 0x5: /* clip */
724 case 0x8: /* bset */
725 case 0x9: /* bclr */
726 case 0xa: /* btgl */
727 case 0xb: /* btst */
728 func (stream, "%s\t%s, %s, #%d", mnemonic_alu20[op],
729 gpr_map[rt], gpr_map[ra], IMM1U (insn));
730 return;
731
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)]);
736 return;
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 */
744 case 0x2f: /* div */
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]);
750 return;
751
752 case 0x4f: /* flmism */
753 case 0x68: /* mulsr64 */
754 case 0x69: /* mulr64 */
755 case 0x73: /* maddr32 */
756 case 0x75: /* msubr32 */
757 op = insn & 0x3f;
758 func (stream, "%s\t%s, %s, %s", mnemonic_alu21[op],
759 gpr_map[rt], gpr_map[ra], gpr_map[rb]);
760 return;
761 default:
762 func (stream, UNKNOWN_INSN_MSG);
763 return;
764 }
765 }
766
767 static void
768 print_insn32_jreg (bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info, uint32_t insn)
769 {
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;
780
781 switch (op)
782 {
783 case 0: /* jr */
784 func (stream, "%s%s\t%s", mnemonic_ret[op >> 5],
785 dtit_on[dtit], gpr_map[rb]);
786 return;
787
788 case 0x20: /* ret */
789 func (stream, "%s%s\t%s", mnemonic_ret[op >> 5],
790 dtit_off[dtit], gpr_map[rb]);
791 return;
792 case 0x60: /* ifret */
793 break;
794 case 1: /* jral */
795 case 2: /* jrnez */
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]);
799 return;
800 default: /* unknown */
801 func (stream, UNKNOWN_INSN_MSG);
802 break;
803 }
804 }
805
806 static void
807 print_insn32_misc (bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info,
808 uint32_t insn)
809 {
810 int op = insn & 0x1f;
811 int rt = RT5 (insn);
812 unsigned int id;
813 fprintf_ftype func = info->fprintf_func;
814 void *stream = info->stream;
815
816 static const char *keyword_standby[] =
817 {
818 "no_wake_grant", "wake_grant", "wait_done",
819 };
820 static const char *keyword_tlbop[] =
821 {
822 "TRD", "TWR", "RWR", "RWLK", "UNLK", "PB", "INV", "FLUA"
823 };
824
825 switch (op)
826 {
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]);
831 else
832 func (stream, "standby\t%d", id);
833 return;
834 case 0x1: /* cctl */
835 func (stream, "cctl\t!FIXME");
836 return;
837 case 0x8: /* dsb */
838 case 0x9: /* isb */
839 case 0xd: /* isync */
840 case 0xc: /* msync */
841 case 0x4: /* iret */
842 func (stream, "%s", mnemonic_misc[op]);
843 return;
844 case 0x5: /* trap */
845 case 0xa: /* break */
846 case 0xb: /* syscall */
847 id = __GF (insn, 5, 15);
848 func (stream, "%s\t%d", mnemonic_misc[op], id);
849 return;
850 case 0x2: /* mfsr */
851 case 0x3: /* mtsr */
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)]);
855 return;
856 case 0x6: /* teqz */
857 case 0x7: /* tnez */
858 id = __GF (insn, 5, 15);
859 func (stream, "%s\t%s, %d", mnemonic_misc[op], gpr_map[rt], id);
860 return;
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]);
865 else
866 func (stream, "tlbop\t%d", id);
867 return;
868 }
869 }
870
871 static void
872 print_insn32_fpu (bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info,
873 uint32_t insn)
874 {
875 int op = insn & 0xf;
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;
880 int dp = 0;
881 int dp_insn = 0;
882 char wd = 's';
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;
889
890 switch (op)
891 {
892 case 0x0: /* fs1 */
893 case 0x8: /* fd1 */
894 dp = (op & 0x8) ? 1 : 0;
895 if (dp)
896 {
897 wd = 'd';
898 dp_insn = 14;
899 }
900 else
901 {
902 wd = 's';
903 dp_insn = 0;
904 }
905 switch (mask_sub_op)
906 {
907 case 0x0:
908 case 0x1:
909 case 0x2:
910 case 0x3:
911 case 0x4:
912 case 0x5:
913 case 0x8:
914 case 0x9:
915 case 0xc:
916 case 0xd:
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);
920 return;
921 case 0x6:
922 case 0x7:
923 func (stream, "%s\t$f%c%d, $f%c%d, $fs%d",
924 mnemonic_alu[mask_sub_op + dp_insn],
925 wd, rt, wd, ra, rb);
926 return;
927 case 0xf:
928 if (dp)
929 {
930 wd = 'd';
931 dp_insn = 0x1d;
932 }
933 else
934 {
935 wd = 's';
936 dp_insn = 0;
937 }
938
939 switch (mask_f2op)
940 {
941 case 0x0:
942 if (dp)
943 func (stream, "%s\t$fs%d, $fd%d",
944 mnemonic_fpu_2op[mask_f2op + dp_insn], rt, ra);
945 else
946 func (stream, "%s\t$fd%d, $fs%d",
947 mnemonic_fpu_2op[mask_f2op + dp_insn], rt, ra);
948 return;
949 case 0x1:
950 case 0x5:
951 func (stream, "%s\t$f%c%d, $f%c%d",
952 mnemonic_fpu_2op[mask_f2op + dp_insn], wd, rt, wd, ra);
953 return;
954 case 0x8:
955 case 0xc:
956 func (stream, "%s\t$f%c%d, $fs%d",
957 mnemonic_fpu_2op[mask_f2op + dp_insn], wd, rt, ra);
958 return;
959 case 0x10:
960 case 0x14:
961 case 0x18:
962 case 0x1c:
963 func (stream, "%s\t$fs%d, $f%c%d",
964 mnemonic_fpu_2op[mask_f2op + dp_insn], rt, wd, ra);
965 return;
966 }
967 }
968 case 0x1: /* mfcp */
969 switch (mask_sub_op)
970 {
971 case 0x0:
972 func (stream, "fmfsr\t%s, $fs%d", gpr_map[rt], ra);
973 return;
974 case 0x1:
975 func (stream, "fmfdr\t%s, $fd%d", gpr_map[rt], ra);
976 return;
977 case 0xc:
978 if (mask_cfg)
979 func (stream, "fmfcsr\t%s", gpr_map[rt]);
980 else
981 func (stream, "fmfcfg\t%s", gpr_map[rt]);
982 return;
983 }
984 case 0x2: /* fls */
985 if (mask_bi)
986 func (stream, "fls.bi\t$fs%d, [%s], (%s << %d)",
987 rt, gpr_map[ra], gpr_map[rb], sv);
988 else
989 func (stream, "fls\t$fs%d, [%s + (%s << %d)]",
990 rt, gpr_map[ra], gpr_map[rb], sv);
991 return;
992 case 0x3: /* fld */
993 if (mask_bi)
994 func (stream, "fld.bi\t$fd%d, [%s], (%s << %d)",
995 rt, gpr_map[ra], gpr_map[rb], sv);
996 else
997 func (stream, "fld\t$fd%d, [%s + (%s << %d)]",
998 rt, gpr_map[ra], gpr_map[rb], sv);
999 return;
1000 case 0x4: /* fs2 */
1001 func (stream, "%s\t$fs%d, $fs%d, $fs%d",
1002 mnemonic_fs2_cmp[mask_sub_op], rt, ra, rb);
1003 return;
1004 case 0x9: /* mtcp */
1005 switch (mask_sub_op)
1006 {
1007 case 0x0:
1008 func (stream, "fmtsr\t%s, $fs%d", gpr_map[rt], ra);
1009 return;
1010 case 0x1:
1011 func (stream, "fmtdr\t%s, $fd%d", gpr_map[rt], ra);
1012 return;
1013 case 0xc:
1014 func (stream, "fmtcsr\t%s", gpr_map[rt]);
1015 return;
1016 }
1017 case 0xa: /* fss */
1018 if (mask_bi)
1019 func (stream, "fss.bi\t$fs%d, [%s], (%s << %d)",
1020 rt, gpr_map[ra], gpr_map[rb], sv);
1021 else
1022 func (stream, "fss\t$fs%d, [%s + (%s << %d)]",
1023 rt, gpr_map[ra], gpr_map[rb], sv);
1024 return;
1025 case 0xb: /* fsd */
1026 if (mask_bi)
1027 func (stream, "fsd.bi\t$fd%d, [%s], (%s << %d)",
1028 rt, gpr_map[ra], gpr_map[rb], sv);
1029 else
1030 func (stream, "fsd\t$fd%d, [%s + (%s << %d)]",
1031 rt, gpr_map[ra], gpr_map[rb], sv);
1032 return;
1033 case 0xc: /* fd2 */
1034 func (stream, "%s\t$fs%d, $fd%d, $fd%d",
1035 mnemonic_fd2_cmp[mask_sub_op], rt, ra, rb);
1036 return;
1037 }
1038 }
1039
1040 static void
1041 print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn)
1042 {
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);
1049 uint32_t shift;
1050 fprintf_ftype func = info->fprintf_func;
1051 void *stream = info->stream;
1052
1053 switch (op)
1054 {
1055 case 0x0: /* lbi */
1056 case 0x1: /* lhi */
1057 case 0x2: /* lwi */
1058 case 0x3: /* ldi */
1059 case 0x8: /* sbi */
1060 case 0x9: /* shi */
1061 case 0xa: /* swi */
1062 case 0xb: /* sdi */
1063 case 0x10: /* lbsi */
1064 case 0x11: /* lhsi */
1065 case 0x12: /* lwsi */
1066 shift = op & 0x3;
1067 func (stream, "%s\t%s, [%s + #%d]",
1068 mnemonic_op6[op], gpr_map[rt], gpr_map[ra], imm15s << shift);
1069 return;
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 */
1081 shift = op & 0x3;
1082 func (stream, "%s\t%s, [%s], #%d",
1083 mnemonic_op6[op], gpr_map[rt], gpr_map[ra], imm15s << shift);
1084 return;
1085 case 0x13: /* dprefi */
1086 {
1087 const char *subtype = "???";
1088 char wd = 'w';
1089
1090 shift = 2;
1091
1092 /* d-bit */
1093 if (rt & 0x10)
1094 {
1095 wd = 'd';
1096 shift = 3;
1097 }
1098
1099 if ((rt & 0xf) < ARRAY_SIZE (keyword_dpref))
1100 subtype = keyword_dpref[rt & 0xf];
1101
1102 func (stream, "%s.%c\t%s, [%s + #%d]",
1103 mnemonic_op6[op], wd, subtype, gpr_map[ra], imm15s << shift);
1104 }
1105 return;
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));
1110 return;
1111 case 0x18: /* LWC */
1112 case 0x19: /* SWC */
1113 case 0x1a: /* LDC */
1114 case 0x1b: /* SDC */
1115 if (__GF (insn, 13, 2) == 0)
1116 {
1117 char ls = (op & 1) ? 's' : 'l';
1118 char wd = (op & 2) ? 'd' : 's';
1119
1120 if (insn & __BIT (12))
1121 {
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);
1124 }
1125 else
1126 {
1127 func (stream, "f%c%ci\t$f%c%d, [%s + %d]", ls, wd,
1128 wd, rt, gpr_map[ra], IMMS (insn, 12) << 2);
1129 }
1130 }
1131 else
1132 {
1133 char ls = (op & 1) ? 's' : 'l';
1134 char wd = (op & 2) ? 'd' : 'w';
1135 int cp = __GF (insn, 13, 2);
1136
1137 if (insn & __BIT (12))
1138 {
1139 func (stream, "cp%c%ci\tcp%d, $cpr%d, [%s], %d", ls, wd,
1140 cp, rt, gpr_map[ra], IMMS (insn, 12) << 2);
1141 }
1142 else
1143 {
1144 func (stream, "cp%c%ci\tcp%d, $cpr%d, [%s + %d]", ls, wd,
1145 cp, rt, gpr_map[ra], IMMS (insn, 12) << 2);
1146 }
1147 }
1148 return;
1149 case 0x1c: /* MEM */
1150 print_insn32_mem (pc, info, insn);
1151 return;
1152 case 0x1d: /* LSMW */
1153 {
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", "?"};
1160
1161 /* lsmwzb only always increase. */
1162 if ((insn & 0x3) == 2)
1163 di = "";
1164
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);
1168 }
1169 return;
1170 case 0x1e: /* HWGP */
1171 op = __GF (insn, 17, 3);
1172 switch (op)
1173 {
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);
1179 return;
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);
1184 return;
1185 }
1186 return;
1187 case 0x1f: /* SBGP */
1188 if (insn & __BIT (19))
1189 func (stream, "addi.gp\t%s, %d",
1190 gpr_map[rt], IMMS (insn, 19));
1191 else
1192 func (stream, "sbi.gp\t%s, [+ %d]",
1193 gpr_map[rt], IMMS (insn, 19));
1194 return;
1195 case 0x20: /* ALU_1 */
1196 print_insn32_alu1 (pc, info, insn);
1197 return;
1198 case 0x21: /* ALU_2 */
1199 print_insn32_alu2 (pc, info, insn);
1200 return;
1201 case 0x22: /* movi */
1202 func (stream, "movi\t%s, %d", gpr_map[rt], IMMS (insn, 20));
1203 return;
1204 case 0x23: /* sethi */
1205 func (stream, "sethi\t%s, 0x%x", gpr_map[rt], IMMU (insn, 20));
1206 return;
1207 case 0x24: /* ji, jal */
1208 /* FIXME: Handle relocation. */
1209 if (info->flags & INSN_HAS_RELOC)
1210 pc = 0;
1211 func (stream, "%s\t", ((insn & __BIT (24)) ? "jal" : "j"));
1212 info->print_address_func ((IMMS (insn, 24) << 1) + pc, info);
1213 return;
1214 case 0x25: /* jreg */
1215 print_insn32_jreg (pc, info, insn);
1216 return;
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);
1221 return;
1222 case 0x27: /* br2 */
1223 func (stream, "%s\t%s, ", mnemonic_br2[__GF (insn, 16, 4)],
1224 gpr_map[rt]);
1225 info->print_address_func ((IMMS (insn, 16) << 1) + pc, info);
1226 return;
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);
1233 return;
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);
1240 return;
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);
1245 return;
1246 case 0x32: /* misc */
1247 print_insn32_misc (pc, info, insn);
1248 return;
1249 case 0x35: /* FPU */
1250 print_insn32_fpu (pc, info, insn);
1251 return;
1252 }
1253 }
1254
1255 int
1256 print_insn_nds32 (bfd_vma pc, disassemble_info *info)
1257 {
1258 int status;
1259 bfd_byte buf[4];
1260 uint32_t insn;
1261
1262 status = info->read_memory_func (pc, (bfd_byte *) buf, 2, info);
1263 if (status)
1264 return -1;
1265
1266 /* 16-bit instruction. */
1267 if (buf[0] & 0x80)
1268 {
1269 insn = bfd_getb16 (buf);
1270 print_insn16 (pc, info, insn);
1271 return 2;
1272 }
1273
1274 /* 32-bit instructions. */
1275 status = info->read_memory_func (pc + 2, (bfd_byte *) buf + 2, 2, info);
1276 if (status)
1277 return -1;
1278
1279 insn = bfd_getb32 (buf);
1280 print_insn32 (pc, info, insn);
1281
1282 return 4;
1283 }