xref: /netbsd-src/external/gpl3/gdb/dist/opcodes/nds32-dis.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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 }
1284