xref: /netbsd-src/external/gpl3/gdb/dist/opcodes/nds32-asm.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 <config.h>
24 
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <assert.h>
29 
30 #include "safe-ctype.h"
31 #include "libiberty.h"
32 #include "hashtab.h"
33 #include "bfd.h"
34 
35 #include "opcode/nds32.h"
36 #include "nds32-asm.h"
37 
38 /* There at at most MAX_LEX_NUM lexical elements in a syntax.  */
39 #define MAX_LEX_NUM		32
40 /* A operand in syntax string should be at most this long.  */
41 #define MAX_LEX_LEN		32
42 /* The max length of a keyword can be.  */
43 #define MAX_KEYWORD_LEN		32
44 /* This LEX is a plain char or operand.  */
45 #define IS_LEX_CHAR(c)		(((c) >> 7) == 0)
46 #define LEX_SET_FIELD(c)	((c) | SYN_FIELD)
47 #define LEX_GET_FIELD(c)	operand_fields[((c) & 0xff)]
48 /* Get the char in this lexical element.  */
49 #define LEX_CHAR(c)		((c) & 0xff)
50 
51 #define USRIDX(group, usr)	((group) | ((usr) << 5))
52 #define SRIDX(major, minor, ext) \
53 				(((major) << 7) | ((minor) << 3) | (ext))
54 
55 static int parse_re2 (struct nds32_asm_desc *, struct nds32_asm_insn *,
56 		      char **, int64_t *);
57 static int parse_fe5 (struct nds32_asm_desc *, struct nds32_asm_insn *,
58 		      char **, int64_t *);
59 static int parse_pi5 (struct nds32_asm_desc *, struct nds32_asm_insn *,
60 		      char **, int64_t *);
61 
62 
63 enum
64 {
65   /* This is a field (operand) of just a separator char.  */
66   SYN_FIELD = 0x100,
67 
68   /* This operand is used for input or output.  (define or use)  */
69   SYN_INPUT = 0x1000,
70   SYN_OUTPUT = 0x2000,
71   SYN_LOPT = 0x4000,
72   SYN_ROPT = 0x8000,
73 
74   /* Hardware resources.  */
75   HW_GPR = 0,
76   HW_USR,
77   HW_DXR,
78   HW_SR,
79   HW_FSR,
80   HW_FDR,
81   HW_CP,	/* Co-processor ID.  */
82   HW_CPR,	/* Co-processor registers.  */
83   HW_ABDIM,	/* [ab][di]m? flag for LSMWA?.  */
84   HW_ABM,	/* [ab]m? flag for LSMWZB.  */
85   HW_DTITON,
86   HW_DTITOFF,
87   HW_DPREF_ST,
88   HW_CCTL_ST0,
89   HW_CCTL_ST1,
90   HW_CCTL_ST2,
91   HW_CCTL_ST3,
92   HW_CCTL_ST4,
93   HW_CCTL_ST5,
94   HW_CCTL_LV,
95   HW_TLBOP_ST,
96   HW_STANDBY_ST,
97   HW_MSYNC_ST,
98   _HW_LAST,
99   /* TODO: Maybe we should add a new type to distinguish address and
100 	   const int.  Only the former allows symbols and relocations.  */
101   HW_INT,
102   HW_UINT
103 };
104 
105 
106 /* These are operand prefixes for input/output semantic.
107 
108      %   input
109      =   output
110      &   both
111      {}  optional operand
112 
113    Field table for operands and bit-fields.  */
114 
115 static const field_t operand_fields[] =
116 {
117   {"rt",	20, 5, 0, HW_GPR, NULL},
118   {"ra",	15, 5, 0, HW_GPR, NULL},
119   {"rb",	10, 5, 0, HW_GPR, NULL},
120   {"rd",	5, 5, 0, HW_GPR, NULL},
121   {"fst",	20, 5, 0, HW_FSR, NULL},
122   {"fsa",	15, 5, 0, HW_FSR, NULL},
123   {"fsb",	10, 5, 0, HW_FSR, NULL},
124   {"fdt",	20, 5, 0, HW_FDR, NULL},
125   {"fda",	15, 5, 0, HW_FDR, NULL},
126   {"fdb",	10, 5, 0, HW_FDR, NULL},
127   {"cprt",	20, 5, 0, HW_CPR, NULL},
128   {"cp",	13, 2, 0, HW_CP, NULL},
129   {"sh",	5, 5, 0, HW_UINT, NULL},	/* sh in ALU instructions.  */
130   {"sv",	8, 2, 0, HW_UINT, NULL},	/* sv in MEM instructions.  */
131   {"dt",	21, 1, 0, HW_DXR, NULL},
132   {"usr",	10, 10, 0, HW_USR, NULL},	/* User Special Registers.  */
133   {"sr",	10, 10, 0, HW_SR, NULL},	/* System Registers.  */
134   {"ridx",	10, 10, 0, HW_UINT, NULL},	/* Raw value for mfusr/mfsr.  */
135   {"enb4",	6, 9, 0, HW_UINT, NULL},	/* Enable4 for LSMW.  */
136   {"swid",	5, 15, 0, HW_UINT, NULL},
137   {"stdby_st",	5, 2, 0, HW_STANDBY_ST, NULL},
138   {"tlbop_st",	5, 5, 0, HW_TLBOP_ST, NULL},
139   {"tlbop_stx",	5, 5, 0, HW_UINT, NULL},
140   {"cctl_st0",	5, 5, 0, HW_CCTL_ST0, NULL},
141   {"cctl_st1",	5, 5, 0, HW_CCTL_ST1, NULL},
142   {"cctl_st2",	5, 5, 0, HW_CCTL_ST2, NULL},
143   {"cctl_st3",	5, 5, 0, HW_CCTL_ST3, NULL},
144   {"cctl_st4",	5, 5, 0, HW_CCTL_ST4, NULL},
145   {"cctl_st5",	5, 5, 0, HW_CCTL_ST5, NULL},
146   {"cctl_stx",	5, 5, 0, HW_UINT, NULL},
147   {"cctl_lv",	10, 1, 0, HW_CCTL_LV, NULL},
148   {"msync_st",	5, 3, 0, HW_MSYNC_ST, NULL},
149   {"msync_stx",	5, 3, 0, HW_UINT, NULL},
150   {"dpref_st",	20, 5, 0, HW_DPREF_ST, NULL},
151   {"rt5",	5, 5, 0, HW_GPR, NULL},
152   {"ra5",	0, 5, 0, HW_GPR, NULL},
153   {"rt4",	5, 4, 0, HW_GPR, NULL},
154   {"rt3",	6, 3, 0, HW_GPR, NULL},
155   {"rt38",	8, 3, 0, HW_GPR, NULL},	/* rt3 used in 38 form.  */
156   {"ra3",	3, 3, 0, HW_GPR, NULL},
157   {"rb3",	0, 3, 0, HW_GPR, NULL},
158   {"rt5e",	4, 4, 1, HW_GPR, NULL},	/* movd44 */
159   {"ra5e",	0, 4, 1, HW_GPR, NULL},	/* movd44 */
160   {"re2",	5, 2, 0, HW_GPR, parse_re2},	/* re in push25/pop25.  */
161   {"fe5",	0, 5, 2, HW_UINT, parse_fe5},	/* imm5u in lwi45.fe.  */
162   {"pi5",	0, 5, 0, HW_UINT, parse_pi5},	/* imm5u in movpi45.  */
163   {"abdim",	2, 3, 0, HW_ABDIM, NULL},	/* Flags for LSMW.  */
164   {"abm",	2, 3, 0, HW_ABM, NULL},	/* Flags for LSMWZB.  */
165   {"dtiton",	8, 2, 0, HW_DTITON, NULL},
166   {"dtitoff",	8, 2, 0, HW_DTITOFF, NULL},
167 
168   {"i5s",	0, 5, 0, HW_INT, NULL},
169   {"i10s",	0, 10, 0, HW_INT, NULL},
170   {"i15s",	0, 15, 0, HW_INT, NULL},
171   {"i19s",	0, 19, 0, HW_INT, NULL},
172   {"i20s",	0, 20, 0, HW_INT, NULL},
173   {"i8s1",	0, 8, 1, HW_INT, NULL},
174   {"i11br3",	8, 11, 0, HW_INT, NULL},
175   {"i14s1",	0, 14, 1, HW_INT, NULL},
176   {"i15s1",	0, 15, 1, HW_INT, NULL},
177   {"i16s1",	0, 16, 1, HW_INT, NULL},
178   {"i18s1",	0, 18, 1, HW_INT, NULL},
179   {"i24s1",	0, 24, 1, HW_INT, NULL},
180   {"i8s2",	0, 8, 2, HW_INT, NULL},
181   {"i12s2",	0, 12, 2, HW_INT, NULL},
182   {"i15s2",	0, 15, 2, HW_INT, NULL},
183   {"i17s2",	0, 17, 2, HW_INT, NULL},
184   {"i19s2",	0, 19, 2, HW_INT, NULL},
185   {"i3u",	0, 3, 0, HW_UINT, NULL},
186   {"i5u",	0, 5, 0, HW_UINT, NULL},
187   {"ib5u",	10, 5, 0, HW_UINT, NULL},	/* imm5 field in ALU.  */
188   {"ib5s",	10, 5, 0, HW_INT, NULL},	/* imm5 field in ALU.  */
189   {"i9u",	0, 9, 0, HW_UINT, NULL},	/* break16/ex9.it */
190   {"ia3u",	3, 3, 0, HW_UINT, NULL},	/* bmski33, fexti33 */
191   {"i8u",	0, 8, 0, HW_UINT, NULL},
192   {"i15u",	0, 15, 0, HW_UINT, NULL},
193   {"i20u",	0, 20, 0, HW_UINT, NULL},
194   {"i3u1",	0, 3, 1, HW_UINT, NULL},
195   {"i9u1",	0, 9, 1, HW_UINT, NULL},
196   {"i3u2",	0, 3, 2, HW_UINT, NULL},
197   {"i6u2",	0, 6, 2, HW_UINT, NULL},
198   {"i7u2",	0, 7, 2, HW_UINT, NULL},
199   {"i5u3",	0, 5, 3, HW_UINT, NULL},	/* pop25/pop25 */
200   {"i15s3",	0, 15, 3, HW_UINT, NULL},	/* dprefi.d */
201 
202   {NULL, 0, 0, 0, 0, NULL}
203 };
204 
205 
206 #define OP6(op6)		(N32_OP6_ ## op6 << 25)
207 #define DEF_REG(r)		(__BIT (r))
208 #define USE_REG(r)		(__BIT (r))
209 #define RT(r)			(r << 20)
210 #define RA(r)			(r << 15)
211 #define RB(r)			(r << 10)
212 #define RA5(r)			(r)
213 
214 static struct nds32_opcode nds32_opcodes[] =
215 {
216   /* ALU1 */
217 #define ALU1(sub)	(OP6 (ALU1) | N32_ALU1_ ## sub)
218   {"add", "=rt,%ra,%rb",		ALU1 (ADD), 4, ATTR_ALL, 0, NULL, 0, NULL},
219   {"sub", "=rt,%ra,%rb",		ALU1 (SUB), 4, ATTR_ALL, 0, NULL, 0, NULL},
220   {"and", "=rt,%ra,%rb",		ALU1 (AND), 4, ATTR_ALL, 0, NULL, 0, NULL},
221   {"xor", "=rt,%ra,%rb",		ALU1 (XOR), 4, ATTR_ALL, 0, NULL, 0, NULL},
222   {"or", "=rt,%ra,%rb",			ALU1 (OR), 4, ATTR_ALL, 0, NULL, 0, NULL},
223   {"nor", "=rt,%ra,%rb",		ALU1 (NOR), 4, ATTR_ALL, 0, NULL, 0, NULL},
224   {"slt", "=rt,%ra,%rb",		ALU1 (SLT), 4, ATTR_ALL, 0, NULL, 0, NULL},
225   {"slts", "=rt,%ra,%rb",		ALU1 (SLTS), 4, ATTR_ALL, 0, NULL, 0, NULL},
226   {"slli", "=rt,%ra,%ib5u",		ALU1 (SLLI), 4, ATTR_ALL, 0, NULL, 0, NULL},
227   {"srli", "=rt,%ra,%ib5u",		ALU1 (SRLI), 4, ATTR_ALL, 0, NULL, 0, NULL},
228   {"srai", "=rt,%ra,%ib5u",		ALU1 (SRAI), 4, ATTR_ALL, 0, NULL, 0, NULL},
229   {"rotri", "=rt,%ra,%ib5u",		ALU1 (ROTRI), 4, ATTR_ALL, 0, NULL, 0, NULL},
230   {"sll", "=rt,%ra,%rb",		ALU1 (SLL), 4, ATTR_ALL, 0, NULL, 0, NULL},
231   {"srl", "=rt,%ra,%rb",		ALU1 (SRL), 4, ATTR_ALL, 0, NULL, 0, NULL},
232   {"sra", "=rt,%ra,%rb",		ALU1 (SRA), 4, ATTR_ALL, 0, NULL, 0, NULL},
233   {"rotr", "=rt,%ra,%rb",		ALU1 (ROTR), 4, ATTR_ALL, 0, NULL, 0, NULL},
234   {"seb", "=rt,%ra",			ALU1 (SEB), 4, ATTR_ALL, 0, NULL, 0, NULL},
235   {"seh", "=rt,%ra",			ALU1 (SEH), 4, ATTR_ALL, 0, NULL, 0, NULL},
236   {"bitc", "=rt,%ra,%rb",		ALU1 (BITC), 4, ATTR_V3, 0, NULL, 0, NULL},
237   {"zeh", "=rt,%ra",			ALU1 (ZEH), 4, ATTR_ALL, 0, NULL, 0, NULL},
238   {"wsbh", "=rt,%ra",			ALU1 (WSBH), 4, ATTR_ALL, 0, NULL, 0, NULL},
239   {"divsr", "=rt,=rd,%ra,%rb",		ALU1 (DIVSR), 4, ATTR (DIV) | ATTR_V2UP, 0, NULL, 0, NULL},
240   {"divr", "=rt,=rd,%ra,%rb",		ALU1 (DIVR), 4, ATTR (DIV) | ATTR_V2UP, 0, NULL, 0, NULL},
241   {"sva", "=rt,%ra,%rb",		ALU1 (SVA), 4, ATTR_ALL, 0, NULL, 0, NULL},
242   {"svs", "=rt,%ra,%rb",		ALU1 (SVS), 4, ATTR_ALL, 0, NULL, 0, NULL},
243   {"cmovz", "=rt,%ra,%rb",		ALU1 (CMOVZ), 4, ATTR_ALL, 0, NULL, 0, NULL},
244   {"cmovn", "=rt,%ra,%rb",		ALU1 (CMOVN), 4, ATTR_ALL, 0, NULL, 0, NULL},
245   {"add_slli", "=rt,%ra,%rb,%sh",	ALU1 (ADD), 4, ATTR_V3, 0, NULL, 0, NULL},
246   {"sub_slli", "=rt,%ra,%rb,%sh",	ALU1 (SUB), 4, ATTR_V3, 0, NULL, 0, NULL},
247   {"and_slli", "=rt,%ra,%rb,%sh",	ALU1 (AND), 4, ATTR_V3, 0, NULL, 0, NULL},
248   {"xor_slli", "=rt,%ra,%rb,%sh",	ALU1 (XOR), 4, ATTR_V3, 0, NULL, 0, NULL},
249   {"or_slli", "=rt,%ra,%rb,%sh",	ALU1 (OR), 4, ATTR_V3, 0, NULL, 0, NULL},
250   {"or_srli", "=rt,%ra,%rb,%sh",	ALU1 (OR_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL},
251   {"add_srli", "=rt,%ra,%rb,%sh",	ALU1 (ADD_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL},
252   {"sub_srli", "=rt,%ra,%rb,%sh",	ALU1 (SUB_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL},
253   {"and_srli", "=rt,%ra,%rb,%sh",	ALU1 (AND_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL},
254   {"xor_srli", "=rt,%ra,%rb,%sh",	ALU1 (XOR_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL},
255 
256   /* ALU2 */
257 #define ALU2(sub)	(OP6 (ALU2) | N32_ALU2_ ## sub)
258   {"max", "=rt,%ra,%rb",	ALU2 (MAX), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
259   {"min", "=rt,%ra,%rb",	ALU2 (MIN), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
260   {"ave", "=rt,%ra,%rb",	ALU2 (AVE), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
261   {"abs", "=rt,%ra",		ALU2 (ABS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
262   {"clips", "=rt,%ra,%ib5s",	ALU2 (CLIPS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
263   {"clip", "=rt,%ra,%ib5u",	ALU2 (CLIP), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
264   {"clo", "=rt,%ra",		ALU2 (CLO), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
265   {"clz", "=rt,%ra",		ALU2 (CLZ), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
266   {"bset", "=rt,%ra,%ib5u",	ALU2 (BSET), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
267   {"bclr", "=rt,%ra,%ib5u",	ALU2 (BCLR), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
268   {"btgl", "=rt,%ra,%ib5u",	ALU2 (BTGL), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
269   {"btst", "=rt,%ra,%ib5u",	ALU2 (BTST), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL},
270   {"bse", "=rt,%ra,=rb",	ALU2 (BSE), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL},
271   {"bsp", "=rt,%ra,=rb",	ALU2 (BSP), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL},
272   {"ffb", "=rt,%ra,%rb",	ALU2 (FFB), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
273   {"ffmism", "=rt,%ra,%rb",	ALU2 (FFMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
274   {"ffzmism", "=rt,%ra,%rb",	ALU2 (FFZMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
275   {"mfusr", "=rt,%usr",		ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
276   {"mtusr", "%rt,%usr",		ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
277   {"mfusr", "=rt,%ridx",	ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
278   {"mtusr", "%rt,%ridx",	ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
279   {"mul", "=rt,%ra,%rb",	ALU2 (MUL), 4, ATTR_ALL, 0, NULL, 0, NULL},
280   {"mults64", "=dt,%ra,%rb",	ALU2 (MULTS64), 4, ATTR_ALL, 0, NULL, 0, NULL},
281   {"mult64", "=dt,%ra,%rb",	ALU2 (MULT64), 4, ATTR_ALL, 0, NULL, 0, NULL},
282   {"madds64", "=dt,%ra,%rb",	ALU2 (MADDS64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL},
283   {"madd64", "=dt,%ra,%rb",	ALU2 (MADD64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL},
284   {"msubs64", "=dt,%ra,%rb",	ALU2 (MSUBS64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL},
285   {"msub64", "=dt,%ra,%rb",	ALU2 (MSUB64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL},
286   {"divs", "=dt,%ra,%rb",	ALU2 (DIVS), 4, ATTR (DIV) | ATTR (DXREG), 0, NULL, 0, NULL},
287   {"div", "=dt,%ra,%rb",	ALU2 (DIV), 4, ATTR (DIV) | ATTR (DXREG), 0, NULL, 0, NULL},
288   {"mult32", "=dt,%ra,%rb",	ALU2 (MULT32), 4, ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL},
289   {"madd32", "=dt,%ra,%rb",	ALU2 (MADD32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL},
290   {"msub32", "=dt,%ra,%rb",	ALU2 (MSUB32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL},
291   {"ffbi", "=rt,%ra,%ib5u",	ALU2 (FFBI) | __BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
292   {"flmism", "=rt,%ra,%rb",	ALU2 (FLMISM) | __BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
293   {"mulsr64", "=rt,%ra,%rb",	ALU2 (MULSR64)| __BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
294   {"mulr64", "=rt,%ra,%rb",	ALU2 (MULR64) | __BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
295   {"maddr32", "=rt,%ra,%rb",	ALU2 (MADDR32) | __BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL},
296   {"msubr32", "=rt,%ra,%rb",	ALU2 (MSUBR32) | __BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL},
297 
298   /* MISC */
299 #define MISC(sub)	(OP6 (MISC) | N32_MISC_ ## sub)
300   {"standby", "%stdby_st",	MISC (STANDBY), 4, ATTR_ALL, 0, NULL, 0, NULL},
301   {"cctl", "%ra,%cctl_st0",	MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
302   {"cctl", "%ra,%cctl_st1{,%cctl_lv}", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
303   {"cctl", "=rt,%ra,%cctl_st2",	MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
304   {"cctl", "%rt,%ra,%cctl_st3",	MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
305   {"cctl", "%cctl_st4",		MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
306   {"cctl", "%cctl_st5{,%cctl_lv}", MISC (CCTL), 4, ATTR_V3, 0, NULL, 0, NULL},
307   {"cctl", "=rt,%ra,%cctl_stx,%cctl_lv", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
308   {"mfsr", "=rt,%sr",		MISC (MFSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
309   {"mtsr", "%rt,%sr",		MISC (MTSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
310   {"mfsr", "=rt,%ridx",		MISC (MFSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
311   {"mtsr", "%rt,%ridx",		MISC (MTSR), 4, ATTR_ALL, 0, NULL, 0, NULL},
312   {"iret", "",			MISC (IRET), 4, ATTR_ALL, 0, NULL, 0, NULL},
313   {"trap", "%swid",		MISC (TRAP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
314   {"trap", "",			MISC (TRAP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
315   {"teqz", "%rt,%swid",		MISC (TEQZ), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
316   {"tnez", "%rt,%swid",		MISC (TNEZ), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
317   {"dsb", "",			MISC (DSB), 4, ATTR_ALL, 0, NULL, 0, NULL},
318   {"isb", "",			MISC (ISB), 4, ATTR_ALL, 0, NULL, 0, NULL},
319   {"break", "%swid",		MISC (BREAK), 4, ATTR_ALL, 0, NULL, 0, NULL},
320   {"break", "",			MISC (BREAK), 4, ATTR_ALL, 0, NULL, 0, NULL},
321   {"syscall", "%swid",		MISC (SYSCALL), 4, ATTR_ALL, 0, NULL, 0, NULL},
322   {"msync", "%msync_st",	MISC (MSYNC), 4, ATTR_ALL, 0, NULL, 0, NULL},
323   {"msync", "%msync_stx",	MISC (MSYNC), 4, ATTR_ALL, 0, NULL, 0, NULL},
324   {"isync", "%rt",		MISC (ISYNC), 4, ATTR_ALL, 0, NULL, 0, NULL},
325   {"tlbop", "%ra,%tlbop_st",	MISC (TLBOP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
326   {"tlbop", "%ra,%tlbop_stx",	MISC (TLBOP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
327   {"tlbop", "%rt,%ra,pb",	MISC (TLBOP) | (5 << 5), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
328   {"tlbop", "flua",		MISC (TLBOP) | (7 << 5), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
329 
330   {"setend.l", "",		MISC (MTSR)
331 				| (SRIDX (1, 0, 0) << 10) | __BIT (5), 4, ATTR_ALL, 0, NULL, 0, NULL},
332   {"setend.b", "",		MISC (MTSR)
333 				| (SRIDX (1, 0, 0) << 10) | __BIT (5) | __BIT (20), 4, ATTR_ALL, 0, NULL, 0, NULL},
334   {"setgie.d", "",		MISC (MTSR)
335 				| (SRIDX (1, 0, 0) << 10) | __BIT (6), 4, ATTR_ALL, 0, NULL, 0, NULL},
336   {"setgie.e", "",		MISC (MTSR)
337 				| (SRIDX (1, 0, 0) << 10) | __BIT (6) | __BIT (20), 4, ATTR_ALL, 0, NULL, 0, NULL},
338 
339   /* JI */
340   {"jal", "%i24s1",		OP6 (JI) | __BIT (24), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
341   {"j", "%i24s1",		OP6 (JI), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
342 
343   /* BR1 */
344   {"beq", "%rt,%ra,%i14s1",	OP6 (BR1), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
345   {"bne", "%rt,%ra,%i14s1",	OP6 (BR1) | __BIT (14), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
346 
347   /* BR2 */
348 #define BR2(sub)	(OP6 (BR2) | (N32_BR2_ ## sub << 16))
349   {"beqz", "%rt,%i16s1",	BR2 (BEQZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
350   {"bnez", "%rt,%i16s1",	BR2 (BNEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
351   {"bgez", "%rt,%i16s1",	BR2 (BGEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
352   {"bltz", "%rt,%i16s1",	BR2 (BLTZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
353   {"bgtz", "%rt,%i16s1",	BR2 (BGTZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
354   {"blez", "%rt,%i16s1",	BR2 (BLEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
355   {"bgezal", "%rt,%i16s1",	BR2 (BGEZAL), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
356   {"bltzal", "%rt,%i16s1",	BR2 (BLTZAL), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
357 
358   /* BR3 */
359   {"beqc", "%rt,%i11br3,%i8s1",	OP6 (BR3), 4, ATTR_PCREL | ATTR_V3MUP, 0, NULL, 0, NULL},
360   {"bnec", "%rt,%i11br3,%i8s1",	OP6 (BR3) | __BIT (19), 4, ATTR_PCREL | ATTR_V3MUP, 0, NULL, 0, NULL},
361 
362 #define JREG(sub)	(OP6 (JREG) | N32_JREG_ ## sub)
363   /* JREG */
364   {"jr", "%rb",			JREG (JR), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
365   {"jral", "%rt,%rb",		JREG (JRAL), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
366   {"jral", "%rb",		JREG (JRAL) | RT (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
367   {"jrnez", "%rb",		JREG (JRNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL},
368   {"jralnez", "%rt,%rb",	JREG (JRALNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL},
369   {"jralnez", "%rb",		JREG (JRALNEZ) | RT (30), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL},
370 
371 #define JREG_RET	(1 << 5)
372 #define JREG_IFC	(1 << 6)
373   {"ret", "%rb",		JREG (JR) | JREG_RET, 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
374   {"ret", "",			JREG (JR) | JREG_RET | RB (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
375   {"jral", "%dtiton %rt,%rb",	JREG (JRAL), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
376   {"jral", "%dtiton %rb",	JREG (JRAL) | RT (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL},
377   {"jr", "%dtitoff %rb",	JREG (JR), 4, ATTR (BRANCH) | ATTR_V3MEX_V1, 0, NULL, 0, NULL},
378   {"ret", "%dtitoff %rb",	JREG (JR) | JREG_RET, 4, ATTR (BRANCH) | ATTR_V3MEX_V1, 0, NULL, 0, NULL},
379   {"ifret", "",			JREG (JR) | JREG_IFC | JREG_RET, 4, ATTR (BRANCH) | ATTR (IFC_EXT), 0, NULL, 0, NULL},
380 
381   /* MEM */
382 #define MEM(sub)	(OP6 (MEM) | N32_MEM_ ## sub)
383   {"lb", "=rt,[%ra+(%rb<<%sv)]",                MEM (LB), 4, ATTR_ALL, 0, NULL, 0, NULL},
384   {"lb", "=rt,[%ra+%rb{<<%sv}]",		MEM (LB), 4, ATTR_ALL, 0, NULL, 0, NULL},
385   {"lh", "=rt,[%ra+(%rb<<%sv)]",                MEM (LH), 4, ATTR_ALL, 0, NULL, 0, NULL},
386   {"lh", "=rt,[%ra+%rb{<<%sv}]",		MEM (LH), 4, ATTR_ALL, 0, NULL, 0, NULL},
387   {"lw", "=rt,[%ra+(%rb<<%sv)]",                MEM (LW), 4, ATTR_ALL, 0, NULL, 0, NULL},
388   {"lw", "=rt,[%ra+%rb{<<%sv}]",		MEM (LW), 4, ATTR_ALL, 0, NULL, 0, NULL},
389   {"sb", "=rt,[%ra+(%rb<<%sv)]",                MEM (SB), 4, ATTR_ALL, 0, NULL, 0, NULL},
390   {"sb", "%rt,[%ra+%rb{<<%sv}]",		MEM (SB), 4, ATTR_ALL, 0, NULL, 0, NULL},
391   {"sh", "=rt,[%ra+(%rb<<%sv)]",                MEM (SH), 4, ATTR_ALL, 0, NULL, 0, NULL},
392   {"sh", "%rt,[%ra+%rb{<<%sv}]",		MEM (SH), 4, ATTR_ALL, 0, NULL, 0, NULL},
393   {"sw", "=rt,[%ra+(%rb<<%sv)]",                MEM (SW), 4, ATTR_ALL, 0, NULL, 0, NULL},
394   {"sw", "%rt,[%ra+%rb{<<%sv}]",		MEM (SW), 4, ATTR_ALL, 0, NULL, 0, NULL},
395   {"lb.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (LB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
396   {"lb.bi", "=rt,[%ra],%rb{<<%sv}",		MEM (LB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
397   {"lh.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (LH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
398   {"lh.bi", "=rt,[%ra],%rb{<<%sv}",		MEM (LH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
399   {"lw.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (LW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
400   {"lw.bi", "=rt,[%ra],%rb{<<%sv}",		MEM (LW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
401   {"sb.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (SB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
402   {"sb.bi", "%rt,[%ra],%rb{<<%sv}",		MEM (SB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
403   {"sh.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (SH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
404   {"sh.bi", "%rt,[%ra],%rb{<<%sv}",		MEM (SH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
405   {"sw.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (SW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
406   {"sw.bi", "%rt,[%ra],%rb{<<%sv}",		MEM (SW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
407   {"lbs", "=rt,[%ra+(%rb<<%sv)]",		MEM (LBS), 4, ATTR_ALL, 0, NULL, 0, NULL},
408   {"lbs", "=rt,[%ra+%rb{<<%sv}]",		MEM (LBS), 4, ATTR_ALL, 0, NULL, 0, NULL},
409   {"lhs", "=rt,[%ra+(%rb<<%sv)]",		MEM (LHS), 4, ATTR_ALL, 0, NULL, 0, NULL},
410   {"lhs", "=rt,[%ra+%rb{<<%sv}]",		MEM (LHS), 4, ATTR_ALL, 0, NULL, 0, NULL},
411   {"lbs.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (LBS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
412   {"lbs.bi", "=rt,[%ra],%rb{<<%sv}",		MEM (LBS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
413   {"lhs.bi", "=rt,[%ra],(%rb<<%sv)",		MEM (LHS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
414   {"lhs.bi", "=rt,[%ra],%rb{<<%sv}",		MEM (LHS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
415   {"llw", "=rt,[%ra+(%rb<<%sv)]",		MEM (LLW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
416   {"llw", "=rt,[%ra+%rb{<<%sv}]",		MEM (LLW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
417   {"scw", "%rt,[%ra+(%rb<<%sv)]",		MEM (SCW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
418   {"scw", "%rt,[%ra+%rb{<<%sv}]",		MEM (SCW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
419   {"lbup", "=rt,[%ra+(%rb<<%sv)]",		MEM (LBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
420   {"lbup", "=rt,[%ra+%rb{<<%sv}]",		MEM (LBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
421   {"lwup", "=rt,[%ra+(%rb<<%sv)]",		MEM (LWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
422   {"lwup", "=rt,[%ra+%rb{<<%sv}]",		MEM (LWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
423   {"sbup", "%rt,[%ra+(%rb<<%sv)]",		MEM (SBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
424   {"sbup", "%rt,[%ra+%rb{<<%sv}]",		MEM (SBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
425   {"swup", "%rt,[%ra+(%rb<<%sv)]",		MEM (SWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
426   {"swup", "%rt,[%ra+%rb{<<%sv}]",		MEM (SWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
427   {"dpref", "%dpref_st,[%ra+(%rb<<%sv)]",	MEM (DPREF), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
428   {"dpref", "%dpref_st,[%ra+%rb{<<%sv}]",	MEM (DPREF), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
429 
430   /* LBGP */
431   {"lbi.gp", "=rt,[+%i19s]",	OP6 (LBGP), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
432   {"lbsi.gp", "=rt,[+%i19s]",	OP6 (LBGP) | __BIT (19), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
433 
434   /* SBGP */
435   {"sbi.gp", "%rt,[+%i19s]",	OP6 (SBGP), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
436   {"addi.gp", "=rt,%i19s",	OP6 (SBGP) | __BIT (19), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
437 
438   /* HWGP */
439   {"lhi.gp", "=rt,[+%i18s1]",	OP6 (HWGP), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
440   {"lhsi.gp", "=rt,[+%i18s1]",	OP6 (HWGP) | (2 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
441   {"shi.gp", "%rt,[+%i18s1]",	OP6 (HWGP) | (4 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
442   {"lwi.gp", "=rt,[+%i17s2]",	OP6 (HWGP) | (6 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
443   {"swi.gp", "%rt,[+%i17s2]",	OP6 (HWGP) | (7 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL},
444 
445 #define LSMW(sub)	(OP6 (LSMW) | N32_LSMW_ ## sub)
446   {"lmw", "%abdim %rt,[%ra],%rb{,%enb4}",		LSMW (LSMW), 4, ATTR_ALL, 0, NULL, 0, NULL},
447   {"smw", "%abdim %rt,[%ra],%rb{,%enb4}",		LSMW (LSMW) | __BIT (5), 4, ATTR_ALL, 0, NULL, 0, NULL},
448   {"lmwa", "%abdim %rt,[%ra],%rb{,%enb4}",	LSMW (LSMWA), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
449   {"smwa", "%abdim %rt,[%ra],%rb{,%enb4}",	LSMW (LSMWA) | __BIT (5), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL},
450   {"lmwzb", "%abm %rt,[%ra],%rb{,%enb4}",	LSMW (LSMWZB), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
451   {"smwzb", "%abm %rt,[%ra],%rb{,%enb4}",	LSMW (LSMWZB) | __BIT (5), 4, ATTR (STR_EXT), 0, NULL, 0, NULL},
452 
453 
454 #define SIMD(sub)	(OP6 (SIMD) | N32_SIMD_ ## sub)
455   {"pbsad", "%rt,%rb,%ra",	SIMD (PBSAD), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL},
456   {"pbsada", "%rt,%rb,%ra",	SIMD (PBSADA), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL},
457 
458   /* COP */
459 #if 0
460   {"cpe1", 0, 0, NULL, 0, NULL},
461   {"mfcp", 0, 0, NULL, 0, NULL},
462   {"cplw", 0, 0, NULL, 0, NULL},
463   {"cplw.bi", 0, 0, NULL, 0, NULL},
464   {"cpld", 0, 0, NULL, 0, NULL},
465   {"cpld.bi", 0, 0, NULL, 0, NULL},
466   {"cpe2", 0, 0, NULL, 0, NULL},
467 
468   {"cpe3", 0, 0, NULL, 0, NULL},
469   {"mtcp", 0, 0, NULL, 0, NULL},
470   {"cpsw", 0, 0, NULL, 0, NULL},
471   {"cpsw.bi", 0, 0, NULL, 0, NULL},
472   {"cpsd", 0, 0, NULL, 0, NULL},
473   {"cpsd.bi", 0, 0, NULL, 0, NULL},
474   {"cpe4", 0, 0, NULL, 0, NULL},
475 #endif
476 
477   /* FPU */
478 #define FS1(sub)	(OP6 (COP) | N32_FPU_FS1 | (N32_FPU_FS1_ ## sub << 6))
479   {"fadds",   "=fst,%fsa,%fsb",	FS1 (FADDS),	4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
480   {"fsubs",   "=fst,%fsa,%fsb",	FS1 (FSUBS),	4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
481   {"fcpynss", "=fst,%fsa,%fsb",	FS1 (FCPYNSS),	4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
482   {"fcpyss",  "=fst,%fsa,%fsb",	FS1 (FCPYSS),	4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
483   {"fmadds",  "=fst,%fsa,%fsb", FS1 (FMADDS),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
484   {"fmsubs",  "=fst,%fsa,%fsb", FS1 (FMSUBS),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
485   {"fcmovns", "=fst,%fsa,%fsb", FS1 (FCMOVNS),  4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
486   {"fcmovzs", "=fst,%fsa,%fsb", FS1 (FCMOVZS),  4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
487   {"fnmadds", "=fst,%fsa,%fsb", FS1 (FNMADDS),  4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
488   {"fnmsubs", "=fst,%fsa,%fsb", FS1 (FNMSUBS),  4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
489   {"fmuls",   "=fst,%fsa,%fsb", FS1 (FMULS),	4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
490   {"fdivs",   "=fst,%fsa,%fsb", FS1 (FDIVS),	4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
491 
492 #define FS1_F2OP(sub)	(OP6 (COP) | N32_FPU_FS1 | (N32_FPU_FS1_F2OP << 6) \
493 			 | (N32_FPU_FS1_F2OP_ ## sub << 10))
494   {"fs2d",    "=fdt,%fsa",	FS1_F2OP (FS2D),    4, ATTR (FPU) | ATTR (FPU_SP_EXT) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
495   {"fsqrts",  "=fst,%fsa",	FS1_F2OP (FSQRTS),  4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
496   {"fabss",   "=fst,%fsa",	FS1_F2OP (FABSS),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
497   {"fui2s",   "=fst,%fsa",	FS1_F2OP (FUI2S),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
498   {"fsi2s",   "=fst,%fsa",	FS1_F2OP (FSI2S),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
499   {"fs2ui",   "=fst,%fsa",	FS1_F2OP (FS2UI),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
500   {"fs2ui.z", "=fst,%fsa",	FS1_F2OP (FS2UI_Z), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
501   {"fs2si",   "=fst,%fsa",	FS1_F2OP (FS2SI),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
502   {"fs2si.z", "=fst,%fsa",	FS1_F2OP (FS2SI_Z), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
503 
504 #define FS2(sub)	(OP6 (COP) | N32_FPU_FS2 | (N32_FPU_FS2_ ## sub << 6))
505   {"fcmpeqs",   "=fst,%fsa,%fsb", FS2 (FCMPEQS),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
506   {"fcmplts",   "=fst,%fsa,%fsb", FS2 (FCMPLTS),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
507   {"fcmples",   "=fst,%fsa,%fsb", FS2 (FCMPLES),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
508   {"fcmpuns",   "=fst,%fsa,%fsb", FS2 (FCMPUNS),   4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
509   {"fcmpeqs.e", "=fst,%fsa,%fsb", FS2 (FCMPEQS_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
510   {"fcmplts.e", "=fst,%fsa,%fsb", FS2 (FCMPLTS_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
511   {"fcmples.e", "=fst,%fsa,%fsb", FS2 (FCMPLES_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
512   {"fcmpuns.e", "=fst,%fsa,%fsb", FS2 (FCMPUNS_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL},
513 
514 #define FD1(sub)	(OP6 (COP) | N32_FPU_FD1 | (N32_FPU_FD1_ ## sub << 6))
515   {"faddd",   "=fdt,%fda,%fdb", FD1 (FADDD),    4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
516   {"fsubd",   "=fdt,%fda,%fdb", FD1 (FSUBD),    4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
517   {"fcpynsd", "=fdt,%fda,%fdb", FD1 (FCPYNSD),  4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
518   {"fcpysd",  "=fdt,%fda,%fdb", FD1 (FCPYSD),   4, ATTR (FPU), 0, NULL, 0, NULL},
519   {"fmaddd",  "=fdt,%fda,%fdb", FD1 (FMADDD),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
520   {"fmsubd",  "=fdt,%fda,%fdb", FD1 (FMSUBD),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
521   {"fcmovnd", "=fdt,%fda,%fsb", FD1 (FCMOVND),  4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
522   {"fcmovzd", "=fdt,%fda,%fsb", FD1 (FCMOVZD),  4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
523   {"fnmaddd", "=fdt,%fda,%fdb", FD1 (FNMADDD),  4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
524   {"fnmsubd", "=fdt,%fda,%fdb", FD1 (FNMSUBD),  4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
525   {"fmuld",   "=fdt,%fda,%fdb", FD1 (FMULD),    4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
526   {"fdivd",   "=fdt,%fda,%fdb", FD1 (FDIVD),    4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
527 
528 #define FD1_F2OP(sub)	(OP6 (COP) | N32_FPU_FD1 | (N32_FPU_FD1_F2OP << 6) \
529 			 | (N32_FPU_FD1_F2OP_ ## sub << 10))
530   {"fd2s",    "=fst,%fda",	FD1_F2OP (FD2S),    4, ATTR (FPU) | ATTR (FPU_SP_EXT) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
531   {"fsqrtd",  "=fdt,%fda",	FD1_F2OP (FSQRTD),  4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
532   {"fabsd",   "=fdt,%fda",	FD1_F2OP (FABSD),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
533   {"fui2d",   "=fdt,%fsa",	FD1_F2OP (FUI2D),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
534   {"fsi2d",   "=fdt,%fsa",	FD1_F2OP (FSI2D),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
535   {"fd2ui",   "=fst,%fda",	FD1_F2OP (FD2UI),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
536   {"fd2ui.z", "=fst,%fda",	FD1_F2OP (FD2UI_Z), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
537   {"fd2si",   "=fst,%fda",	FD1_F2OP (FD2SI),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
538   {"fd2si.z", "=fst,%fda",	FD1_F2OP (FD2SI_Z), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
539 
540 #define FD2(sub)	(OP6 (COP) | N32_FPU_FD2 | (N32_FPU_FD2_ ## sub << 6))
541   {"fcmpeqd",   "=fst,%fda,%fdb", FD2 (FCMPEQD),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
542   {"fcmpltd",   "=fst,%fda,%fdb", FD2 (FCMPLTD),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
543   {"fcmpled",   "=fst,%fda,%fdb", FD2 (FCMPLED),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
544   {"fcmpund",   "=fst,%fda,%fdb", FD2 (FCMPUND),   4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
545   {"fcmpeqd.e", "=fst,%fda,%fdb", FD2 (FCMPEQD_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
546   {"fcmpltd.e", "=fst,%fda,%fdb", FD2 (FCMPLTD_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
547   {"fcmpled.e", "=fst,%fda,%fdb", FD2 (FCMPLED_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
548   {"fcmpund.e", "=fst,%fda,%fdb", FD2 (FCMPUND_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL},
549 
550 #define MFCP(sub)	(OP6 (COP) | N32_FPU_MFCP | (N32_FPU_MFCP_ ## sub << 6))
551   {"fmfsr",   "=rt,%fsa", MFCP (FMFSR),   4, ATTR (FPU), 0, NULL, 0, NULL},
552   {"fmfdr",   "=rt,%fda", MFCP (FMFDR),   4, ATTR (FPU), 0, NULL, 0, NULL},
553 
554 #define MFCP_XR(sub)	(OP6 (COP) | N32_FPU_MFCP | (N32_FPU_MFCP_XR << 6) \
555 			 | (N32_FPU_MFCP_XR_ ## sub << 10))
556   {"fmfcfg", "=rt"	, MFCP_XR(FMFCFG), 4, ATTR (FPU), 0, NULL, 0, NULL},
557   {"fmfcsr", "=rt"	, MFCP_XR(FMFCSR), 4, ATTR (FPU), 0, NULL, 0, NULL},
558 
559 #define MTCP(sub)	(OP6 (COP) | N32_FPU_MTCP | (N32_FPU_MTCP_ ## sub << 6))
560   {"fmtsr",   "%rt,=fsa", MTCP (FMTSR),   4, ATTR (FPU), 0, NULL, 0, NULL},
561   {"fmtdr",   "%rt,=fda", MTCP (FMTDR),   4, ATTR (FPU), 0, NULL, 0, NULL},
562 
563 #define MTCP_XR(sub)	(OP6 (COP) | N32_FPU_MTCP | (N32_FPU_MTCP_XR << 6) \
564 			 | (N32_FPU_MTCP_XR_ ## sub << 10))
565   {"fmtcsr", "%rt"	, MTCP_XR(FMTCSR), 4, ATTR (FPU), 0, NULL, 0, NULL},
566 
567 #define FPU_MEM(sub)		(OP6 (COP) | N32_FPU_ ## sub)
568 #define FPU_MEMBI(sub)	(OP6 (COP) | N32_FPU_ ## sub | 0x2 << 6)
569 #define FPU_RA_IMMBI(sub)	(OP6 (sub) | __BIT (12))
570   {"fls",     "=fst,[%ra+(%rb<<%sv)]", FPU_MEM (FLS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
571   {"fls",     "=fst,[%ra+%rb{<<%sv}]", FPU_MEM (FLS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
572   {"fls.bi",  "=fst,[%ra],(%rb<<%sv)", FPU_MEMBI (FLS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
573   {"fls.bi",  "=fst,[%ra],%rb{<<%sv}", FPU_MEMBI (FLS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
574   {"fss",     "=fst,[%ra+(%rb<<%sv)]", FPU_MEM (FSS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
575   {"fss",     "=fst,[%ra+%rb{<<%sv}]", FPU_MEM (FSS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
576   {"fss.bi",  "=fst,[%ra],(%rb<<%sv)", FPU_MEMBI (FSS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
577   {"fss.bi",  "=fst,[%ra],%rb{<<%sv}", FPU_MEMBI (FSS),	  4, ATTR (FPU), 0, NULL, 0, NULL},
578   {"fld",     "=fdt,[%ra+(%rb<<%sv)]", FPU_MEM (FLD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
579   {"fld",     "=fdt,[%ra+%rb{<<%sv}]", FPU_MEM (FLD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
580   {"fld.bi",  "=fdt,[%ra],(%rb<<%sv)", FPU_MEMBI (FLD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
581   {"fld.bi",  "=fdt,[%ra],%rb{<<%sv}", FPU_MEMBI (FLD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
582   {"fsd",     "=fdt,[%ra+(%rb<<%sv)]", FPU_MEM (FSD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
583   {"fsd",     "=fdt,[%ra+%rb{<<%sv}]", FPU_MEM (FSD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
584   {"fsd.bi",  "=fdt,[%ra],(%rb<<%sv)", FPU_MEMBI (FSD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
585   {"fsd.bi",  "=fdt,[%ra],%rb{<<%sv}", FPU_MEMBI (FSD),	  4, ATTR (FPU), 0, NULL, 0, NULL},
586   {"flsi",    "=fst,[%ra{+%i12s2}]",   OP6 (LWC),	  4, ATTR (FPU), 0, NULL, 0, NULL},
587   {"flsi.bi", "=fst,[%ra],%i12s2",     FPU_RA_IMMBI (LWC),4, ATTR (FPU), 0, NULL, 0, NULL},
588   {"fssi",    "=fst,[%ra{+%i12s2}]",   OP6 (SWC),	  4, ATTR (FPU), 0, NULL, 0, NULL},
589   {"fssi.bi", "=fst,[%ra],%i12s2",     FPU_RA_IMMBI (SWC),4, ATTR (FPU), 0, NULL, 0, NULL},
590   {"fldi",    "=fdt,[%ra{+%i12s2}]",   OP6 (LDC),	  4, ATTR (FPU), 0, NULL, 0, NULL},
591   {"fldi.bi", "=fdt,[%ra],%i12s2",     FPU_RA_IMMBI (LDC),4, ATTR (FPU), 0, NULL, 0, NULL},
592   {"fsdi",    "=fdt,[%ra{+%i12s2}]",   OP6 (SDC),	  4, ATTR (FPU), 0, NULL, 0, NULL},
593   {"fsdi.bi", "=fdt,[%ra],%i12s2",     FPU_RA_IMMBI (SDC),4, ATTR (FPU), 0, NULL, 0, NULL},
594 
595   /* AEXT */
596 
597   {"lbi", "=rt,[%ra{+%i15s}]",			OP6 (LBI), 4, ATTR_ALL, 0, NULL, 0, NULL},
598   {"lhi", "=rt,[%ra{+%i15s1}]",			OP6 (LHI), 4, ATTR_ALL, 0, NULL, 0, NULL},
599   {"lwi", "=rt,[%ra{+%i15s2}]",			OP6 (LWI), 4, ATTR_ALL, 0, NULL, 0, NULL},
600   {"lbi.bi", "=rt,[%ra],%i15s",			OP6 (LBI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
601   {"lhi.bi", "=rt,[%ra],%i15s1",		OP6 (LHI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
602   {"lwi.bi", "=rt,[%ra],%i15s2",		OP6 (LWI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
603   {"sbi", "%rt,[%ra{+%i15s}]",			OP6 (SBI), 4, ATTR_ALL, 0, NULL, 0, NULL},
604   {"shi", "%rt,[%ra{+%i15s1}]",			OP6 (SHI), 4, ATTR_ALL, 0, NULL, 0, NULL},
605   {"swi", "%rt,[%ra{+%i15s2}]",			OP6 (SWI), 4, ATTR_ALL, 0, NULL, 0, NULL},
606   {"sbi.bi", "%rt,[%ra],%i15s",			OP6 (SBI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
607   {"shi.bi", "%rt,[%ra],%i15s1",		OP6 (SHI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
608   {"swi.bi", "%rt,[%ra],%i15s2",		OP6 (SWI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
609   {"lbsi", "=rt,[%ra{+%i15s}]",			OP6 (LBSI), 4, ATTR_ALL, 0, NULL, 0, NULL},
610   {"lhsi", "=rt,[%ra{+%i15s1}]",		OP6 (LHSI), 4, ATTR_ALL, 0, NULL, 0, NULL},
611   {"lwsi", "=rt,[%ra{+%i15s2}]",		OP6 (LWSI), 4, ATTR_ALL, 0, NULL, 0, NULL},
612   {"lbsi.bi", "=rt,[%ra],%i15s",		OP6 (LBSI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
613   {"lhsi.bi", "=rt,[%ra],%i15s1",		OP6 (LHSI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
614   {"lwsi.bi", "=rt,[%ra],%i15s2",		OP6 (LWSI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL},
615   {"cplwi", "%cp,=cprt,[%ra{+%i12s2}]",		OP6 (LWC), 4, 0, 0, NULL, 0, NULL},
616   {"cpswi", "%cp,=cprt,[%ra{+%i12s2}]",		OP6 (SWC), 4, 0, 0, NULL, 0, NULL},
617   {"cpldi", "%cp,%cprt,[%ra{+%i12s2}]",		OP6 (LDC), 4, 0, 0, NULL, 0, NULL},
618   {"cpsdi", "%cp,%cprt,[%ra{+%i12s2}]",		OP6 (SDC), 4, 0, 0, NULL, 0, NULL},
619   {"cplwi.bi", "%cp,=cprt,[%ra],%i12s2",	OP6 (LWC) | __BIT (12), 4, 0, 0, NULL, 0, NULL},
620   {"cpswi.bi", "%cp,=cprt,[%ra],%i12s2",	OP6 (SWC) | __BIT (12), 4, 0, 0, NULL, 0, NULL},
621   {"cpldi.bi", "%cp,%cprt,[%ra],%i12s2",	OP6 (LDC) | __BIT (12), 4, 0, 0, NULL, 0, NULL},
622   {"cpsdi.bi", "%cp,%cprt,[%ra],%i12s2",	OP6 (SDC) | __BIT (12), 4, 0, 0, NULL, 0, NULL},
623   {"movi", "=rt,%i20s",				OP6 (MOVI), 4, ATTR_ALL, 0, NULL, 0, NULL},
624   {"sethi", "=rt,%i20u",			OP6 (SETHI), 4, ATTR_ALL, 0, NULL, 0, NULL},
625   {"addi", "=rt,%ra,%i15s",			OP6 (ADDI), 4, ATTR_ALL, 0, NULL, 0, NULL},
626   {"subri", "=rt,%ra,%i15s",			OP6 (SUBRI), 4, ATTR_ALL, 0, NULL, 0, NULL},
627   {"andi", "=rt,%ra,%i15u",			OP6 (ANDI), 4, ATTR_ALL, 0, NULL, 0, NULL},
628   {"xori", "=rt,%ra,%i15u",			OP6 (XORI), 4, ATTR_ALL, 0, NULL, 0, NULL},
629   {"ori", "=rt,%ra,%i15u",			OP6 (ORI), 4, ATTR_ALL, 0, NULL, 0, NULL},
630   {"slti", "=rt,%ra,%i15s",			OP6 (SLTI), 4, ATTR_ALL, 0, NULL, 0, NULL},
631   {"sltsi", "=rt,%ra,%i15s",			OP6 (SLTSI), 4, ATTR_ALL, 0, NULL, 0, NULL},
632   {"bitci", "=rt,%ra,%i15u",			OP6 (BITCI), 4, ATTR_V3, 0, NULL, 0, NULL},
633   {"dprefi.w", "%dpref_st,[%ra{+%i15s2]}",	OP6 (DPREFI), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
634   {"dprefi.d", "%dpref_st,[%ra{+%i15s3]}",	OP6 (DPREFI) | __BIT (24), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL},
635 
636   /* 16-bit instructions.  */
637   {"mov55", "=rt5,%ra5",		0x8000, 2, ATTR_ALL, 0, NULL, 0, NULL},	/* mov55, $sp, $sp == ifret */
638   {"ifret16", "",			0x83ff, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL},
639   {"movi55", "=rt5,%i5s",		0x8400, 2, ATTR_ALL, 0, NULL, 0, NULL},
640   {"add45", "=rt4,%ra5",		0x8800, 2, ATTR_ALL, 0, NULL, 0, NULL},
641   {"sub45", "=rt4,%ra5",		0x8a00, 2, ATTR_ALL, 0, NULL, 0, NULL},
642   {"addi45", "=rt4,%i5u",		0x8c00, 2, ATTR_ALL, 0, NULL, 0, NULL},
643   {"subi45", "=rt4,%i5u",		0x8e00, 2, ATTR_ALL, 0, NULL, 0, NULL},
644   {"srai45", "=rt4,%i5u",		0x9000, 2, ATTR_ALL, 0, NULL, 0, NULL},
645   {"srli45", "=rt4,%i5u",		0x9200, 2, ATTR_ALL, 0, NULL, 0, NULL},
646   {"slli333", "=rt3,%ra3,%i3u",		0x9400, 2, ATTR_ALL, 0, NULL, 0, NULL},
647   {"zeb33", "=rt3,%ra3",		0x9600, 2, ATTR_ALL, 0, NULL, 0, NULL},
648   {"zeh33", "=rt3,%ra3",		0x9601, 2, ATTR_ALL, 0, NULL, 0, NULL},
649   {"seb33", "=rt3,%ra3",		0x9602, 2, ATTR_ALL, 0, NULL, 0, NULL},
650   {"seh33", "=rt3,%ra3",		0x9603, 2, ATTR_ALL, 0, NULL, 0, NULL},
651   {"xlsb33", "=rt3,%ra3",		0x9604, 2, ATTR_ALL, 0, NULL, 0, NULL},
652   {"x11b33", "=rt3,%ra3",		0x9605, 2, ATTR_ALL, 0, NULL, 0, NULL},
653   {"bmski33", "=rt3,%ia3u",		0x9606, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
654   {"fexti33", "=rt3,%ia3u",		0x9607, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
655   {"add333", "=rt3,%ra3,%rb3",		0x9800, 2, ATTR_ALL, 0, NULL, 0, NULL},
656   {"sub333", "=rt3,%ra3,%rb3",		0x9a00, 2, ATTR_ALL, 0, NULL, 0, NULL},
657   {"addi333", "=rt3,%ra3,%i3u",		0x9c00, 2, ATTR_ALL, 0, NULL, 0, NULL},
658   {"subi333", "=rt3,%ra3,%i3u",		0x9e00, 2, ATTR_ALL, 0, NULL, 0, NULL},
659   {"lwi333", "=rt3,[%ra3{+%i3u2}]",	0xa000, 2, ATTR_ALL, 0, NULL, 0, NULL},
660   {"lwi333.bi", "=rt3,[%ra3],%i3u2",	0xa200, 2, ATTR_ALL, 0, NULL, 0, NULL},
661   {"lhi333", "=rt3,[%ra3{+%i3u1}]",	0xa400, 2, ATTR_ALL, 0, NULL, 0, NULL},
662   {"lbi333", "=rt3,[%ra3{+%i3u}]",	0xa600, 2, ATTR_ALL, 0, NULL, 0, NULL},
663   {"swi333", "%rt3,[%ra3{+%i3u2}]",	0xa800, 2, ATTR_ALL, 0, NULL, 0, NULL},
664   {"swi333.bi", "%rt3,[%ra3],%i3u2",	0xaa00, 2, ATTR_ALL, 0, NULL, 0, NULL},
665   {"shi333", "%rt3,[%ra3{+%i3u1}]",	0xac00, 2, ATTR_ALL, 0, NULL, 0, NULL},
666   {"sbi333", "%rt3,[%ra3{+%i3u}]",	0xae00, 2, ATTR_ALL, 0, NULL, 0, NULL},
667   {"addri36.sp", "%rt3,%i6u2",		0xb000, 2, ATTR_V3MUP, USE_REG (31), NULL, 0, NULL},
668   {"lwi45.fe", "=rt4,%fe5",		0xb200, 2, ATTR_V3MUP, USE_REG (8), NULL, 0, NULL},
669   {"lwi450", "=rt4,[%ra5]",		0xb400, 2, ATTR_ALL, 0, NULL, 0, NULL},
670   {"swi450", "%rt4,[%ra5]",		0xb600, 2, ATTR_ALL, 0, NULL, 0, NULL},
671   {"lwi37", "=rt38,[$fp{+%i7u2}]",	0xb800, 2, ATTR_ALL, USE_REG (28), NULL, 0, NULL},
672   {"swi37", "%rt38,[$fp{+%i7u2}]",	0xb880, 2, ATTR_ALL, USE_REG (28), NULL, 0, NULL},
673   {"beqz38", "%rt38,%i8s1",		0xc000, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
674   {"bnez38", "%rt38,%i8s1",		0xc800, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
675   {"beqs38", "%rt38,%i8s1",		0xd000, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL},
676   {"j8", "%i8s1",			0xd500, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL},
677   {"bnes38", "%rt38,%i8s1",		0xd800, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL},
678   {"jr5", "%ra5",			0xdd00, 2, ATTR_ALL, 0, NULL, 0, NULL},
679   {"ex9.it", "%i5u",			0xdd40, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL},
680   {"ret5", "%ra5",			0xdd80, 2, ATTR_ALL, 0, NULL, 0, NULL},
681   {"ret5", "",				0xdd80 | RA5 (30), 2, ATTR_ALL, 0, NULL, 0, NULL},
682   {"jral5", "%ra5",			0xdd20, 2, ATTR_ALL, 0, NULL, 0, NULL},
683   {"add5.pc", "%ra5",			0xdda0, 2, ATTR_V3, 0, NULL, 0, NULL},
684   {"slts45", "%rt4,%ra5",		0xe000, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL},
685   {"slt45", "%rt4,%ra5",		0xe200, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL},
686   {"sltsi45", "%rt4,%i5u",		0xe400, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL},
687   {"slti45", "%rt4,%i5u",		0xe600, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL},
688   {"beqzs8", "%i8s1",			0xe800, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL},
689   {"bnezs8", "%i8s1",			0xe900, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL},
690   {"ex9.it", "%i9u",			0xea00, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL},
691   {"break16", "%i9u",			0xea00, 2, ATTR_ALL, 0, NULL, 0, NULL},
692   {"addi10.sp", "%i10s",		0xec00, 2, ATTR_V2UP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL},
693   {"lwi37.sp", "=rt38,[+%i7u2]",	0xf000, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL},
694   {"swi37.sp", "%rt38,[+%i7u2]",	0xf080, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL},
695   {"ifcall9", "%i9u1",			0xf800, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL},
696   {"movpi45", "=rt4,%pi5",		0xfa00, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
697   {"push25", "%re2,%i5u3",		0xfc00, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL},
698   {"pop25", "%re2,%i5u3",		0xfc80, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL},
699   {"movd44", "=rt5e,%ra5e",		0xfd00, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
700   {"neg33", "=rt3,%ra3",		0xfe02, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
701   {"not33", "=rt3,%ra3",		0xfe03, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
702   {"mul33", "=rt3,%ra3",		0xfe04, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
703   {"xor33", "=rt3,%ra3",		0xfe05, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
704   {"and33", "=rt3,%ra3",		0xfe06, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
705   {"or33", "=rt3,%ra3",			0xfe07, 2, ATTR_V3MUP, 0, NULL, 0, NULL},
706 
707   /* Alias instructions.  */
708   {"neg", "=rt,%ra",			OP6 (SUBRI), 4, ATTR_ALL, 0, NULL, 0, NULL},
709   {"zeb", "=rt,%ra",			OP6 (ANDI) | 0xff, 4, ATTR_ALL, 0, NULL, 0, NULL},
710   {"nop", "",				ALU1 (SRLI), 4, ATTR_ALL, 0, NULL, 0, NULL},
711   {"nop16", "",				0x9200, 2, ATTR_ALL, 0, NULL, 0, NULL},
712 
713   /* TODO: For some instruction, an operand may refer to a pair of
714 	   register, e.g., mulsr64 or movd44.
715 
716      Some instruction need special constrain, e.g., movpi45,
717 	  break16, ex9.it.  */
718 };
719 
720 static const keyword_t keyword_gpr[] =
721 {
722   {"r0", 0, ATTR (RDREG)}, {"r1", 1, ATTR (RDREG)}, {"r2", 2, ATTR (RDREG)},
723   {"r3", 3, ATTR (RDREG)}, {"r4", 4, ATTR (RDREG)}, {"r5", 5, ATTR (RDREG)},
724   {"r6", 6, ATTR (RDREG)}, {"r7", 7, ATTR (RDREG)}, {"r8", 8, ATTR (RDREG)},
725   {"r9", 9, ATTR (RDREG)}, {"r10", 10, ATTR (RDREG)},
726   {"r11", 11, 0}, {"r12", 12, 0}, {"r13", 13, 0}, {"r14", 14, 0},
727   {"r15", 15, ATTR (RDREG)},
728   {"r16", 16, 0}, {"r17", 17, 0}, {"r18", 18, 0}, {"r19", 19, 0}, {"r20", 20, 0},
729   {"r21", 21, 0}, {"r22", 22, 0}, {"r23", 23, 0}, {"r24", 24, 0}, {"r25", 25, 0},
730   {"r26", 26, 0}, {"r27", 27, 0},
731   {"r28", 28, ATTR (RDREG)}, {"r29", 29, ATTR (RDREG)},
732   {"r30", 30, ATTR (RDREG)}, {"r31", 31, ATTR (RDREG)},
733 
734   {"ta", 15, ATTR (RDREG)}, {"p0", 26, 0}, {"p1", 27, 0},
735   {"fp", 28, ATTR (RDREG)}, {"gp", 29, ATTR (RDREG)},
736   {"lp", 30, ATTR (RDREG)}, {"sp", 31, ATTR (RDREG)},
737 
738   {NULL, 0, 0}
739 };
740 
741 static const keyword_t keyword_usr[] =
742 {
743   {"d0.lo", USRIDX (0, 0), 0},
744   {"d0.hi", USRIDX (0, 1), 0},
745   {"d1.lo", USRIDX (0, 2), 0},
746   {"d1.hi", USRIDX (0, 3), 0},
747   {"itb", USRIDX (0, 28), 0},
748   {"ifc_lp", USRIDX (0, 29), 0},
749   {"pc", USRIDX (0, 31), 0},
750 
751   {"dma_cfg", USRIDX (1, 0), 0},
752   {"dma_gcsw", USRIDX (1, 1), 0},
753   {"dma_chnsel", USRIDX (1, 2), 0},
754   {"dma_act", USRIDX (1, 3), 0},
755   {"dma_setup", USRIDX (1, 4), 0},
756   {"dma_isaddr", USRIDX (1, 5), 0},
757   {"dma_esaddr", USRIDX (1, 6), 0},
758   {"dma_tcnt", USRIDX (1, 7), 0},
759   {"dma_status", USRIDX (1, 8), 0},
760   {"dma_2dset", USRIDX (1, 9), 0},
761   {"dma_rcnt", USRIDX (1, 23), 0},
762   {"dma_hstatus", USRIDX (1, 24), 0},
763   {"dma_2dsctl", USRIDX (1, 25), 0},
764 
765   {"pfmc0", USRIDX (2, 0), 0},
766   {"pfmc1", USRIDX (2, 1), 0},
767   {"pfmc2", USRIDX (2, 2), 0},
768   {"pfm_ctl", USRIDX (2, 4), 0},
769 
770   {NULL, 0, 0}
771 };
772 
773 static const keyword_t keyword_dxr[] =
774 {
775   {"d0", 0, 0}, {"d1", 1, 0}, {NULL, 0, 0}
776 };
777 
778 static const keyword_t keyword_sr[] =
779 {
780   {"cr0", SRIDX (0, 0, 0), 0}, {"cpu_ver", SRIDX (0, 0, 0), 0},
781   {"cr1", SRIDX (0, 1, 0), 0}, {"icm_cfg", SRIDX (0, 1, 0), 0},
782   {"cr2", SRIDX (0, 2, 0), 0}, {"dcm_cfg", SRIDX (0, 2, 0), 0},
783   {"cr3", SRIDX (0, 3, 0), 0}, {"mmu_cfg", SRIDX (0, 3, 0), 0},
784   {"cr4", SRIDX (0, 4, 0), 0}, {"msc_cfg", SRIDX (0, 4, 0), 0},
785   {"cr5", SRIDX (0, 0, 1), 0}, {"core_id", SRIDX (0, 0, 1), 0},
786   {"cr6", SRIDX (0, 5, 0), 0}, {"fucop_exist", SRIDX (0, 5, 0), 0},
787 
788   {"ir0", SRIDX (1, 0, 0), 0}, {"psw", SRIDX (1, 0, 0), 0},
789   {"ir1", SRIDX (1, 0, 1), 0}, {"ipsw", SRIDX (1, 0, 1), 0},
790   {"ir2", SRIDX (1, 0, 2), 0}, {"p_ipsw", SRIDX (1, 0, 2), 0},
791   {"ir3", SRIDX (1, 1, 1), 0}, {"ivb", SRIDX (1, 1, 1), 0},
792   {"ir4", SRIDX (1, 2, 1), 0}, {"p_eva", SRIDX (1, 2, 2), 0},
793   {"ir5", SRIDX (1, 2, 2), 0}, {"eva", SRIDX (1, 2, 1), 0},
794   {"ir6", SRIDX (1, 3, 1), 0}, {"itype", SRIDX (1, 3, 1), 0},
795   {"ir7", SRIDX (1, 3, 2), 0}, {"p_itype", SRIDX (1, 3, 2), 0},
796   {"ir8", SRIDX (1, 4, 1), 0}, {"merr", SRIDX (1, 4, 1), 0},
797   {"ir9", SRIDX (1, 5, 1), 0}, {"ipc", SRIDX (1, 5, 1), 0},
798   {"ir10", SRIDX (1, 5, 2), 0}, {"p_ipc", SRIDX (1, 5, 2), 0},
799   {"ir11", SRIDX (1, 5, 3), 0}, {"oipc", SRIDX (1, 5, 3), 0},
800   {"ir12", SRIDX (1, 6, 2), 0}, {"p_p0", SRIDX (1, 6, 2), 0},
801   {"ir13", SRIDX (1, 7, 2), 0}, {"p_p1", SRIDX (1, 7, 2), 0},
802   {"ir14", SRIDX (1, 8, 0), 0}, {"int_mask", SRIDX (1, 8, 0), 0},
803   {"ir15", SRIDX (1, 9, 0), 0}, {"int_pend", SRIDX (1, 9, 0), 0},
804   {"ir16", SRIDX (1, 10, 0), 0}, {"sp_usr", SRIDX (1, 10, 0), 0},
805   {"ir17", SRIDX (1, 10, 1), 0}, {"sp_priv", SRIDX (1, 10, 1), 0},
806   {"ir18", SRIDX (1, 11, 0), 0}, {"int_pri", SRIDX (1, 11, 0), 0},
807   {"ir19", SRIDX (1, 1, 2), 0}, {"int_ctrl", SRIDX (1, 1, 2), 0},
808   {"ir20", SRIDX (1, 10, 2), 0}, {"sp_usr1", SRIDX (1, 10, 2), 0},
809   {"ir21", SRIDX (1, 10, 3), 0}, {"sp_priv1", SRIDX (1, 10, 3), 0},
810   {"ir22", SRIDX (1, 10, 4), 0}, {"sp_usr2", SRIDX (1, 10, 4), 0},
811   {"ir23", SRIDX (1, 10, 5), 0}, {"sp_priv2", SRIDX (1, 10, 5), 0},
812   {"ir24", SRIDX (1, 10, 6), 0}, {"sp_usr3", SRIDX (1, 10, 6), 0},
813   {"ir25", SRIDX (1, 10, 7), 0}, {"sp_priv3", SRIDX (1, 10, 7), 0},
814   {"ir26", SRIDX (1, 8, 1), 0}, {"int_mask2", SRIDX (1, 8, 1), 0},
815   {"ir27", SRIDX (1, 9, 1), 0}, {"int_pend2", SRIDX (1, 9, 1), 0},
816   {"ir28", SRIDX (1, 11, 1), 0}, {"int_pri2", SRIDX (1, 11, 1), 0},
817   {"ir29", SRIDX (1, 9, 4), 0}, {"int_trigger", SRIDX (1, 9, 4), 0},
818   {"ir30", SRIDX (1, 1, 3), 0},
819 
820   {"mr0", SRIDX (2, 0, 0), 0}, {"mmu_ctl", SRIDX (2, 0, 0), 0},
821   {"mr1", SRIDX (2, 1, 0), 0}, {"l1_pptb", SRIDX (2, 1, 0), 0},
822   {"mr2", SRIDX (2, 2, 0), 0}, {"tlb_vpn", SRIDX (2, 2, 0), 0},
823   {"mr3", SRIDX (2, 3, 0), 0}, {"tlb_data", SRIDX (2, 3, 0), 0},
824   {"mr4", SRIDX (2, 4, 0), 0}, {"tlb_misc", SRIDX (2, 4, 0), 0},
825   {"mr5", SRIDX (2, 5, 0), 0}, {"vlpt_idx", SRIDX (2, 5, 0), 0},
826   {"mr6", SRIDX (2, 6, 0), 0}, {"ilmb", SRIDX (2, 6, 0), 0},
827   {"mr7", SRIDX (2, 7, 0), 0}, {"dlmb", SRIDX (2, 7, 0), 0},
828   {"mr8", SRIDX (2, 8, 0), 0}, {"cache_ctl", SRIDX (2, 8, 0), 0},
829   {"mr9", SRIDX (2, 9, 0), 0}, {"hsmp_saddr", SRIDX (2, 9, 0), 0},
830   {"mr10", SRIDX (2, 9, 1), 0}, {"hsmp_eaddr", SRIDX (2, 9, 1), 0},
831   {"mr11", SRIDX (2, 0, 1), 0}, {"bg_region", SRIDX (2, 0, 1), 0},
832 
833   {"pfr0", SRIDX (4, 0, 0), 0}, {"pfmc0", SRIDX (4, 0, 0), 0},
834   {"pfr1", SRIDX (4, 0, 1), 0}, {"pfmc1", SRIDX (4, 0, 1), 0},
835   {"pfr2", SRIDX (4, 0, 2), 0}, {"pfmc2", SRIDX (4, 0, 2), 0},
836   {"pfr3", SRIDX (4, 1, 0), 0}, {"pfm_ctl", SRIDX (4, 1, 0), 0},
837 
838   {"dmar0", SRIDX (5, 0, 0), 0}, {"dma_cfg", SRIDX (5, 0, 0), 0},
839   {"dmar1", SRIDX (5, 1, 0), 0}, {"dma_gcsw", SRIDX (5, 1, 0), 0},
840   {"dmar2", SRIDX (5, 2, 0), 0}, {"dma_chnsel", SRIDX (5, 2, 0), 0},
841   {"dmar3", SRIDX (5, 3, 0), 0}, {"dma_act", SRIDX (5, 3, 0), 0},
842   {"dmar4", SRIDX (5, 4, 0), 0}, {"dma_setup", SRIDX (5, 4, 0), 0},
843   {"dmar5", SRIDX (5, 5, 0), 0}, {"dma_isaddr", SRIDX (5, 5, 0), 0},
844   {"dmar6", SRIDX (5, 6, 0), 0}, {"dma_esaddr", SRIDX (5, 6, 0), 0},
845   {"dmar7", SRIDX (5, 7, 0), 0}, {"dma_tcnt", SRIDX (5, 7, 0), 0},
846   {"dmar8", SRIDX (5, 8, 0), 0}, {"dma_status", SRIDX (5, 8, 0), 0},
847   {"dmar9", SRIDX (5, 9, 0), 0}, {"dma_2dset", SRIDX (5, 9, 0), 0},
848   {"dmar10", SRIDX (5, 9, 1), 0}, {"dma_2dsctl", SRIDX (5, 9, 1), 0},
849   {"dmar11", SRIDX (5, 7, 1), 0}, {"dma_rcnt", SRIDX (5, 7, 1), 0},
850   {"dmar12", SRIDX (5, 8, 1), 0}, {"dma_hstatus", SRIDX (5, 8, 1), 0},
851 
852   {"idr0", SRIDX (2, 15, 0), 0}, {"sdz_ctl", SRIDX (2, 15, 0), 0},
853   {"idr1", SRIDX (2, 15, 1), 0}, {"n12misc_ctl", SRIDX (2, 15, 1), 0},
854 			      {"misc_ctl", SRIDX (2, 15, 1), 0},
855 
856   {"secur0", SRIDX (6, 0, 0), 0}, {"sfcr", SRIDX (6, 0, 0), 0},
857 
858   {"prusr_acc_ctl", SRIDX (4, 4, 0), 0},
859   {"fucpr", SRIDX (4, 5, 0), 0}, {"fucop_ctl", SRIDX (4, 5, 0), 0},
860 
861   {"dr0", SRIDX (3, 0, 0), 0}, {"bpc0", SRIDX (3, 0, 0), 0},
862   {"dr1", SRIDX (3, 0, 1), 0}, {"bpc1", SRIDX (3, 0, 1), 0},
863   {"dr2", SRIDX (3, 0, 2), 0}, {"bpc2", SRIDX (3, 0, 2), 0},
864   {"dr3", SRIDX (3, 0, 3), 0}, {"bpc3", SRIDX (3, 0, 3), 0},
865   {"dr4", SRIDX (3, 0, 4), 0}, {"bpc4", SRIDX (3, 0, 4), 0},
866   {"dr5", SRIDX (3, 0, 5), 0}, {"bpc5", SRIDX (3, 0, 5), 0},
867   {"dr6", SRIDX (3, 0, 6), 0}, {"bpc6", SRIDX (3, 0, 6), 0},
868   {"dr7", SRIDX (3, 0, 7), 0}, {"bpc7", SRIDX (3, 0, 7), 0},
869   {"dr8", SRIDX (3, 1, 0), 0}, {"bpa0", SRIDX (3, 1, 0), 0},
870   {"dr9", SRIDX (3, 1, 1), 0}, {"bpa1", SRIDX (3, 1, 1), 0},
871   {"dr10", SRIDX (3, 1, 2), 0}, {"bpa2", SRIDX (3, 1, 2), 0},
872   {"dr11", SRIDX (3, 1, 3), 0}, {"bpa3", SRIDX (3, 1, 3), 0},
873   {"dr12", SRIDX (3, 1, 4), 0}, {"bpa4", SRIDX (3, 1, 4), 0},
874   {"dr13", SRIDX (3, 1, 5), 0}, {"bpa5", SRIDX (3, 1, 5), 0},
875   {"dr14", SRIDX (3, 1, 6), 0}, {"bpa6", SRIDX (3, 1, 6), 0},
876   {"dr15", SRIDX (3, 1, 7), 0}, {"bpa7", SRIDX (3, 1, 7), 0},
877   {"dr16", SRIDX (3, 2, 0), 0}, {"bpam0", SRIDX (3, 2, 0), 0},
878   {"dr17", SRIDX (3, 2, 1), 0}, {"bpam1", SRIDX (3, 2, 1), 0},
879   {"dr18", SRIDX (3, 2, 2), 0}, {"bpam2", SRIDX (3, 2, 2), 0},
880   {"dr19", SRIDX (3, 2, 3), 0}, {"bpam3", SRIDX (3, 2, 3), 0},
881   {"dr20", SRIDX (3, 2, 4), 0}, {"bpam4", SRIDX (3, 2, 4), 0},
882   {"dr21", SRIDX (3, 2, 5), 0}, {"bpam5", SRIDX (3, 2, 5), 0},
883   {"dr22", SRIDX (3, 2, 6), 0}, {"bpam6", SRIDX (3, 2, 6), 0},
884   {"dr23", SRIDX (3, 2, 7), 0}, {"bpam7", SRIDX (3, 2, 7), 0},
885   {"dr24", SRIDX (3, 3, 0), 0}, {"bpv0", SRIDX (3, 3, 0), 0},
886   {"dr25", SRIDX (3, 3, 1), 0}, {"bpv1", SRIDX (3, 3, 1), 0},
887   {"dr26", SRIDX (3, 3, 2), 0}, {"bpv2", SRIDX (3, 3, 2), 0},
888   {"dr27", SRIDX (3, 3, 3), 0}, {"bpv3", SRIDX (3, 3, 3), 0},
889   {"dr28", SRIDX (3, 3, 4), 0}, {"bpv4", SRIDX (3, 3, 4), 0},
890   {"dr29", SRIDX (3, 3, 5), 0}, {"bpv5", SRIDX (3, 3, 5), 0},
891   {"dr30", SRIDX (3, 3, 6), 0}, {"bpv6", SRIDX (3, 3, 6), 0},
892   {"dr31", SRIDX (3, 3, 7), 0}, {"bpv7", SRIDX (3, 3, 7), 0},
893   {"dr32", SRIDX (3, 4, 0), 0}, {"bpcid0", SRIDX (3, 4, 0), 0},
894   {"dr33", SRIDX (3, 4, 1), 0}, {"bpcid1", SRIDX (3, 4, 1), 0},
895   {"dr34", SRIDX (3, 4, 2), 0}, {"bpcid2", SRIDX (3, 4, 2), 0},
896   {"dr35", SRIDX (3, 4, 3), 0}, {"bpcid3", SRIDX (3, 4, 3), 0},
897   {"dr36", SRIDX (3, 4, 4), 0}, {"bpcid4", SRIDX (3, 4, 4), 0},
898   {"dr37", SRIDX (3, 4, 5), 0}, {"bpcid5", SRIDX (3, 4, 5), 0},
899   {"dr38", SRIDX (3, 4, 6), 0}, {"bpcid6", SRIDX (3, 4, 6), 0},
900   {"dr39", SRIDX (3, 4, 7), 0}, {"bpcid7", SRIDX (3, 4, 7), 0},
901   {"dr40", SRIDX (3, 5, 0), 0}, {"edm_cfg", SRIDX (3, 5, 0), 0},
902   {"dr41", SRIDX (3, 6, 0), 0}, {"edmsw", SRIDX (3, 6, 0), 0},
903   {"dr42", SRIDX (3, 7, 0), 0}, {"edm_ctl", SRIDX (3, 7, 0), 0},
904   {"dr43", SRIDX (3, 8, 0), 0}, {"edm_dtr", SRIDX (3, 8, 0), 0},
905   {"dr44", SRIDX (3, 9, 0), 0}, {"bpmtc", SRIDX (3, 9, 0), 0},
906   {"dr45", SRIDX (3, 10, 0), 0}, {"dimbr", SRIDX (3, 10, 0), 0},
907   {"dr46", SRIDX (3, 14, 0), 0}, {"tecr0", SRIDX (3, 14, 0), 0},
908   {"dr47", SRIDX (3, 14, 1), 0}, {"tecr1", SRIDX (3, 14, 1), 0},
909   {NULL,0 ,0}
910 };
911 
912 static const keyword_t keyword_cp[] =
913 {
914   {"cp0", 0, 0}, {"cp1", 1, 0}, {"cp2", 2, 0}, {"cp3", 3, 0}, {NULL, 0, 0}
915 };
916 
917 static const keyword_t keyword_cpr[] =
918 {
919   {"cpr0", 0, 0}, {"cpr1", 1, 0}, {"cpr2", 2, 0}, {"cpr3", 3, 0}, {"cpr4", 4, 0},
920   {"cpr5", 5, 0}, {"cpr6", 6, 0}, {"cpr7", 7, 0}, {"cpr8", 8, 0}, {"cpr9", 9, 0},
921   {"cpr10", 10, 0}, {"cpr11", 11, 0}, {"cpr12", 12, 0}, {"cpr13", 13, 0},
922   {"cpr14", 14, 0}, {"cpr15", 15, 0}, {"cpr16", 16, 0}, {"cpr17", 17, 0},
923   {"cpr18", 18, 0}, {"cpr19", 19, 0}, {"cpr20", 20, 0}, {"cpr21", 21, 0},
924   {"cpr22", 22, 0}, {"cpr23", 23, 0}, {"cpr24", 24, 0}, {"cpr25", 25, 0},
925   {"cpr26", 26, 0}, {"cpr27", 27, 0}, {"cpr28", 28, 0}, {"cpr29", 29, 0},
926   {"cpr30", 30, 0}, {"cpr31", 31, 0}, {NULL, 0, 0}
927 };
928 
929 static const keyword_t keyword_fsr[] =
930 {
931   {"fs0", 0, 0}, {"fs1", 1, 0}, {"fs2", 2, 0}, {"fs3", 3, 0}, {"fs4", 4, 0},
932   {"fs5", 5, 0}, {"fs6", 6, 0}, {"fs7", 7, 0}, {"fs8", 8, 0}, {"fs9", 9, 0},
933   {"fs10", 10, 0}, {"fs11", 11, 0}, {"fs12", 12, 0}, {"fs13", 13, 0},
934   {"fs14", 14, 0}, {"fs15", 15, 0}, {"fs16", 16, 0}, {"fs17", 17, 0},
935   {"fs18", 18, 0}, {"fs19", 19, 0}, {"fs20", 20, 0}, {"fs21", 21, 0},
936   {"fs22", 22, 0}, {"fs23", 23, 0}, {"fs24", 24, 0}, {"fs25", 25, 0},
937   {"fs26", 26, 0}, {"fs27", 27, 0}, {"fs28", 28, 0}, {"fs29", 29, 0},
938   {"fs30", 30, 0}, {"fs31", 31, 0}, {NULL, 0 ,0}
939 };
940 
941 static const keyword_t keyword_fdr[] =
942 {
943   {"fd0", 0, 0}, {"fd1", 1, 0}, {"fd2", 2, 0}, {"fd3", 3, 0}, {"fd4", 4, 0},
944   {"fd5", 5, 0}, {"fd6", 6, 0}, {"fd7", 7, 0}, {"fd8", 8, 0}, {"fd9", 9, 0},
945   {"fd10", 10, 0}, {"fd11", 11, 0}, {"fd12", 12, 0}, {"fd13", 13, 0},
946   {"fd14", 14, 0}, {"fd15", 15, 0}, {"fd16", 16, 0}, {"fd17", 17, 0},
947   {"fd18", 18, 0}, {"fd19", 19, 0}, {"fd20", 20, 0}, {"fd21", 21, 0},
948   {"fd22", 22, 0}, {"fd23", 23, 0}, {"fd24", 24, 0}, {"fd25", 25, 0},
949   {"fd26", 26, 0}, {"fd27", 27, 0}, {"fd28", 28, 0}, {"fd29", 29, 0},
950   {"fd30", 30, 0}, {"fd31", 31, 0}, {NULL, 0, 0}
951 };
952 
953 static const keyword_t keyword_abdim[] =
954 {
955   {"bi", 0, 0}, {"bim", 1, 0}, {"bd", 2, 0}, {"bdm", 3, 0},
956   {"ai", 4, 0}, {"aim", 5, 0}, {"ad", 6, 0}, {"adm", 7, 0},
957   {NULL, 0, 0}
958 };
959 
960 static const keyword_t keyword_abm[] =
961 {
962   {"b", 0, 0}, {"bm", 1, 0}, {"a", 4, 0}, {"am", 5, 0}, {NULL, 0, 0}
963 };
964 
965 static const keyword_t keyword_dtiton[] =
966 {
967   {"iton", 1, 0}, {"ton", 3, 0}, {NULL, 0, 0}
968 };
969 
970 static const keyword_t keyword_dtitoff[] =
971 {
972   {"itoff", 1, 0}, {"toff", 3, 0}, {NULL, 0, 0}
973 };
974 
975 static const keyword_t keyword_dpref_st[] =
976 {
977   {"srd", 0, 0}, {"mrd", 1, 0}, {"swr", 2, 0}, {"mwr", 3, 0},
978   {"pte", 4, 0}, {"clwr", 5, 0}, {NULL, 0, 0}
979 };
980 
981 /* CCTL Ra, SubType */
982 static const keyword_t keyword_cctl_st0[] =
983 {
984   {"l1d_ix_inval", 0X0, 0}, {"l1d_ix_wb", 0X1, 0}, {"l1d_ix_wbinval", 0X2, 0},
985   {"l1d_va_fillck", 0XB, 0}, {"l1d_va_ulck", 0XC, 0}, {"l1i_ix_inval", 0X10, 0},
986   {"l1i_va_fillck", 0X1B, 0}, {"l1i_va_ulck", 0X1C, 0},
987   {NULL, 0, 0}
988 };
989 
990 /* CCTL Ra, SubType, level */
991 static const keyword_t keyword_cctl_st1[] =
992 {
993   {"l1d_va_inval", 0X8, 0}, {"l1d_va_wb", 0X9, 0},
994   {"l1d_va_wbinval", 0XA, 0}, {"l1i_va_inval", 0X18, 0},
995   {NULL, 0, 0}
996 };
997 
998 /* CCTL Rt, Ra, SubType */
999 static const keyword_t keyword_cctl_st2[] =
1000 {
1001   {"l1d_ix_rtag", 0X3, 0}, {"l1d_ix_rwd", 0X4, 0},
1002   {"l1i_ix_rtag", 0X13, 0}, {"l1i_ix_rwd", 0X14, 0},
1003   {NULL, 0, 0}
1004 };
1005 
1006 /* CCTL Rb, Ra, SubType */
1007 static const keyword_t keyword_cctl_st3[] =
1008 {
1009   {"l1d_ix_wtag", 0X5, 0}, {"l1d_ix_wwd", 0X6, 0},
1010   {"l1i_ix_wtag", 0X15, 0}, {"l1i_ix_wwd", 0X16, 0},
1011   {NULL, 0, 0}
1012 };
1013 
1014 /* CCTL L1D_INVALALL */
1015 static const keyword_t keyword_cctl_st4[] =
1016 {
1017   {"l1d_invalall", 0x7, 0}, {NULL, 0, 0}
1018 };
1019 
1020 /* CCTL L1D_WBALL, level */
1021 static const keyword_t keyword_cctl_st5[] =
1022 {
1023   {"l1d_wball", 0xf, 0}, {NULL, 0, 0}
1024 };
1025 
1026 static const keyword_t keyword_cctl_lv[] =
1027 {
1028   {"1level", 0, 0}, {"alevel", 1, 0}, {"0", 0, 0}, {"1", 1, 0},
1029   {NULL, 0, 0},
1030 };
1031 
1032 static const keyword_t keyword_tlbop_st[] =
1033 {
1034   {"trd", 0, 0}, {"targetread", 0, 0},
1035   {"twr", 1, 0}, {"targetwrite", 1, 0},
1036   {"rwr", 2, 0}, {"rwrite", 2, 0},
1037   {"rwlk", 3, 0}, {"rwritelock", 3, 0},
1038   {"unlk", 4, 0}, {"unlock", 4, 0},
1039   {"inv", 6, 0}, {"invalidate", 6, 0},
1040   {NULL, 0, 0},
1041   /* "pb" requries two operand and "flua" requires none.  */
1042   /* {"pb", 5, 0}, {"probe", 5, 0},
1043      {"flua", 7, 0}, {"flushall", 0}, */
1044 };
1045 
1046 static const keyword_t keyword_standby_st[] =
1047 {
1048   {"no_wake_grant", 0, 0},
1049   {"wake_grant", 1, 0},
1050   {"wait_done", 2, 0},
1051   {"0", 0, 0},
1052   {"1", 1, 0},
1053   {"2", 2, 0},
1054   {"3", 3, 0},
1055   {NULL, 0, 0},
1056 };
1057 
1058 static const keyword_t keyword_msync_st[] =
1059 {
1060   {"all", 0, 0}, {"store", 1, 0},
1061   {NULL, 0, 0}
1062 };
1063 
1064 
1065 /* Hash table for syntax lex.   */
1066 static htab_t field_htab;
1067 /* Hash table for opcodes.  */
1068 static htab_t opcode_htab;
1069 /* Hash table for hardware resources.  */
1070 static htab_t hw_ktabs[_HW_LAST];
1071 
1072 static hashval_t
1073 htab_hash_hash (const void *p)
1074 {
1075   struct nds32_hash_entry *h = (struct nds32_hash_entry *) p;
1076 
1077   return htab_hash_string (h->name);
1078 }
1079 
1080 static int
1081 htab_hash_eq (const void *p, const void *q)
1082 {
1083   struct nds32_hash_entry *h = (struct nds32_hash_entry *) p;
1084   const char *name = (const char *) q;
1085 
1086   return strcmp (name, h->name) == 0;
1087 }
1088 
1089 
1090 /* Build a hash table for array BASE.  Each element is in size of SIZE,
1091    and it's first element is a pointer to the key of string.
1092    It stops inserting elements until reach an NULL key.  */
1093 
1094 static htab_t
1095 build_hash_table (const void *base, size_t size)
1096 {
1097   htab_t htab;
1098   hashval_t hash;
1099   const char *p;
1100 
1101   htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
1102 			    NULL, xcalloc, free);
1103 
1104   p = base;
1105   while (1)
1106     {
1107       struct nds32_hash_entry **slot;
1108       struct nds32_hash_entry *h;
1109 
1110       h = (struct nds32_hash_entry *) p;
1111 
1112       if (h->name == NULL)
1113 	break;
1114 
1115       hash = htab_hash_string (h->name);
1116       slot = (struct nds32_hash_entry **)
1117 	htab_find_slot_with_hash (htab, h->name, hash, INSERT);
1118 
1119       assert (slot != NULL && *slot == NULL);
1120 
1121       *slot = h;
1122 
1123       p = p + size;
1124     }
1125 
1126   return htab;
1127 }
1128 
1129 /* Build the syntax for a given opcode OPC.  It parses the string
1130    pointed by INSTRUCTION and store the result on SYNTAX, so
1131    when we assemble an instruction, we don't have to parse the syntax
1132    again.  */
1133 
1134 static void
1135 build_opcode_syntax (struct nds32_opcode *opc)
1136 {
1137   char odstr[MAX_LEX_LEN];
1138   const char *str;
1139   const char *end;
1140   lex_t *plex;
1141   int len;
1142   hashval_t hash;
1143   field_t *fd;
1144   int opt = 0;
1145 
1146   /* Check whether it has been initialized.  */
1147   if (opc->syntax)
1148     return;
1149 
1150   opc->syntax = xmalloc (MAX_LEX_NUM * sizeof (lex_t));
1151 
1152   str = opc->instruction;
1153   plex = opc->syntax;
1154   while (*str)
1155     {
1156       int fidx;
1157 
1158       switch (*str)
1159 	{
1160 	case '%': *plex = SYN_INPUT; break;
1161 	case '=': *plex = SYN_OUTPUT; break;
1162 	case '&': *plex = SYN_INPUT | SYN_OUTPUT; break;
1163 	case '{':
1164 	  *plex++ = SYN_LOPT;
1165 	  opt++;
1166 	  str++;
1167 	  continue;
1168 	case '}':
1169 	  *plex++ = SYN_ROPT;
1170 	  str++;
1171 	  continue;
1172 	default:
1173 	  *plex++ = *str++;
1174 	  continue;
1175 	}
1176       str++;
1177 
1178       /* Extract operand.  */
1179       end = str;
1180       while (ISALNUM (*end) || *end == '_')
1181 	end++;
1182       len = end - str;
1183       memcpy (odstr, str, len);
1184       odstr[len] = '\0';
1185 
1186       hash = htab_hash_string (odstr);
1187       fd = (field_t *) htab_find_with_hash (field_htab, odstr, hash);
1188       fidx = fd - operand_fields;
1189 
1190       if (fd == NULL)
1191 	{
1192 	  fprintf (stderr, "Internal error: Unknown operand, %s\n", str);
1193 	}
1194       assert (fd && fidx >= 0 && fidx < (int) ARRAY_SIZE (operand_fields));
1195       *plex |= LEX_SET_FIELD (fidx);
1196 
1197       str += len;
1198       plex++;
1199     }
1200 
1201   *plex = 0;
1202   opc->variant = opt;
1203   return;
1204 
1205   fprintf (stderr, "Unknown lex in assembly syntax, %s.\n", str);
1206   abort ();
1207 }
1208 
1209 /* Initialize the assembler.  It must be called before assembling.  */
1210 
1211 void
1212 nds32_asm_init (nds32_asm_desc_t *pdesc, int flags)
1213 {
1214   int i;
1215   hashval_t hash;
1216   const keyword_t *keywords[_HW_LAST] =
1217   {
1218     keyword_gpr, keyword_usr, keyword_dxr, keyword_sr, keyword_fsr,
1219     keyword_fdr, keyword_cp, keyword_cpr, keyword_abdim, keyword_abm,
1220     keyword_dtiton, keyword_dtitoff, keyword_dpref_st,
1221     keyword_cctl_st0, keyword_cctl_st1, keyword_cctl_st2,
1222     keyword_cctl_st3, keyword_cctl_st4, keyword_cctl_st5,
1223     keyword_cctl_lv, keyword_tlbop_st, keyword_standby_st,
1224     keyword_msync_st,
1225   };
1226 
1227   pdesc->flags = flags;
1228   pdesc->mach = flags & NASM_OPEN_ARCH_MASK;
1229 
1230   /* Build keyword tables.  */
1231   field_htab = build_hash_table (operand_fields,
1232 				 sizeof (operand_fields[0]));
1233 
1234   for (i = 0; i < _HW_LAST; i++)
1235     hw_ktabs[i] = build_hash_table (keywords[i], sizeof (keyword_t));
1236 
1237   /* Build opcode table.  */
1238   opcode_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
1239 				   NULL, xcalloc, free);
1240 
1241   for (i = 0; i < (int) ARRAY_SIZE (nds32_opcodes); i++)
1242     {
1243       struct nds32_opcode **slot;
1244       struct nds32_opcode *opc;
1245 
1246       opc = &nds32_opcodes[i];
1247 
1248       hash = htab_hash_string (opc->opcode);
1249       slot = (struct nds32_opcode **)
1250 	htab_find_slot_with_hash (opcode_htab, opc->opcode, hash, INSERT);
1251 
1252 #define NDS32_PREINIT_SYNTAX
1253 #if defined (NDS32_PREINIT_SYNTAX)
1254       /* Initial SYNTAX when build opcode table, so bug in syntax can be
1255 	 found when initialized rather than used.  */
1256       build_opcode_syntax (opc);
1257 #endif
1258 
1259       if (*slot == NULL)
1260 	{
1261 	  /* This is the new one.  */
1262 	  *slot = opc;
1263 	}
1264       else
1265 	{
1266 	  /* Already exists.  Append to the list.  */
1267 	  opc = *slot;
1268 	  while (opc->next)
1269 	    opc = opc->next;
1270 	  opc->next = &nds32_opcodes[i];
1271 	}
1272     }
1273 }
1274 
1275 /* Parse the input and store operand keyword string in ODSTR.
1276    This function is only used for parsing keywords,
1277    HW_INT/HW_UINT are parsed parse_operand callback handler.  */
1278 
1279 static char *
1280 parse_to_delimiter (char *str, char odstr[MAX_KEYWORD_LEN])
1281 {
1282   char *outp = odstr;
1283 
1284   while (ISALNUM (*str) || *str == '.' || *str == '_')
1285     *outp++ = TOLOWER (*str++);
1286 
1287   *outp = '\0';
1288   return str;
1289 }
1290 
1291 /* Parse the operand of push25/pop25.  */
1292 
1293 static int
1294 parse_re2 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
1295 	   struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
1296 	   char **pstr, int64_t *value)
1297 {
1298   char *end = *pstr;
1299   char odstr[MAX_KEYWORD_LEN];
1300   keyword_t *k;
1301   hashval_t hash;
1302 
1303   if (*end == '$')
1304     end++;
1305   end = parse_to_delimiter (end, odstr);
1306 
1307   hash = htab_hash_string (odstr);
1308   k = htab_find_with_hash (hw_ktabs[HW_GPR], odstr, hash);
1309 
1310   if (k == NULL)
1311     return NASM_ERR_OPERAND;
1312 
1313   if (k->value == 6)
1314     *value = 0;
1315   else if (k->value == 8)
1316     *value = 1;
1317   else if (k->value == 10)
1318     *value = 2;
1319   else if (k->value == 14)
1320     *value = 3;
1321   else
1322     return NASM_ERR_OPERAND;
1323 
1324   *pstr = end;
1325   return NASM_R_CONST;
1326 }
1327 
1328 /* Parse the operand of lwi45.fe.  */
1329 
1330 static int
1331 parse_fe5 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn,
1332 	   char **pstr, int64_t *value)
1333 {
1334   int r;
1335 
1336   r = pdesc->parse_operand (pdesc, pinsn, pstr, value);
1337   if (r != NASM_R_CONST)
1338     return r;
1339 
1340   /* 128 == 32 << 2.  Leave the shift to parse_opreand,
1341      so it can check whether it is a multiple of 4.  */
1342   *value = 128 + *value;
1343   return r;
1344 }
1345 
1346 /* Parse the operand of movpi45.  */
1347 
1348 static int
1349 parse_pi5 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn,
1350 	   char **pstr, int64_t *value)
1351 {
1352   int r;
1353 
1354   r = pdesc->parse_operand (pdesc, pinsn, pstr, value);
1355   if (r != NASM_R_CONST)
1356     return r;
1357 
1358   *value -= 16;
1359   return r;
1360 }
1361 
1362 /* Generic operand parse base on the information provided by the field.  */
1363 
1364 static int
1365 parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
1366 	       char **str, int syn)
1367 {
1368   char odstr[MAX_KEYWORD_LEN];
1369   char *end;
1370   hashval_t hash;
1371   const field_t *fld = &LEX_GET_FIELD (syn);
1372   keyword_t *k;
1373   int64_t value;
1374   int r;
1375   uint64_t modifier = 0;
1376 
1377   end = *str;
1378 
1379   if (fld->parse)
1380     {
1381       r = fld->parse (pdesc, pinsn, &end, &value);
1382       goto done;
1383     }
1384 
1385   if (fld->hw_res < _HW_LAST)
1386     {
1387       /* Parse the operand in assembly code.  */
1388       if (*end == '$')
1389 	end++;
1390       end = parse_to_delimiter (end, odstr);
1391 
1392       hash = htab_hash_string (odstr);
1393       k = htab_find_with_hash (hw_ktabs[fld->hw_res], odstr, hash);
1394 
1395       if (k == NULL)
1396 	{
1397 	  pdesc->result = NASM_ERR_OPERAND;
1398 	  return 0;
1399 	}
1400 
1401       if (fld->hw_res == HW_GPR && (pdesc->flags & NASM_OPEN_REDUCED_REG)
1402 	  && (k->attr & ATTR (RDREG)) == 0)
1403 	{
1404 	  /* Register not allowed in reduced register.  */
1405 	  pdesc->result = NASM_ERR_REG_REDUCED;
1406 	  return 0;
1407 	}
1408 
1409       if (fld->hw_res == HW_GPR)
1410 	{
1411 	  if (syn & SYN_INPUT)
1412 	    pinsn->defuse |= USE_REG (k->value);
1413 	  if (syn & SYN_OUTPUT)
1414 	    pinsn->defuse |= DEF_REG (k->value);
1415 	}
1416 
1417       value = k->value;
1418       if (fld->hw_res == HW_GPR && (fld->bitsize + fld->shift) == 4)
1419 	value = nds32_r54map[value];
1420     }
1421   else if (fld->hw_res == HW_INT || fld->hw_res == HW_UINT)
1422     {
1423       if (*end == '#')
1424 	end++;
1425 
1426       /* Handle modifiers.  Do we need to make a table for modifiers?
1427 	 Do we need to check unknown modifier?  */
1428       if (strncasecmp (end, "hi20(", 5) == 0)
1429 	{
1430 	  modifier |= NASM_ATTR_HI20;
1431 	  end += 5;
1432 	}
1433       else if (strncasecmp (end, "lo12(", 5) == 0)
1434 	{
1435 	  modifier |= NASM_ATTR_LO12;
1436 	  end += 5;
1437 	}
1438       else if (strncasecmp (end, "lo20(", 5) == 0)
1439 	{
1440 	  /* e.g., movi */
1441 	  modifier |= NASM_ATTR_LO20;
1442 	  end += 5;
1443 	}
1444 
1445       r = pdesc->parse_operand (pdesc, pinsn, &end, &value);
1446       if (modifier)
1447 	{
1448 	  /* Consume the ')' of modifier.  */
1449 	  end++;
1450 	  pinsn->attr |= modifier;
1451 	}
1452 
1453       switch (r)
1454 	{
1455 	case NASM_R_ILLEGAL:
1456 	  pdesc->result = NASM_ERR_OPERAND;
1457 	  return 0;
1458 	case NASM_R_SYMBOL:
1459 	  /* This field needs special fix-up.  */
1460 	  pinsn->field = fld;
1461 	  break;
1462 	case NASM_R_CONST:
1463 	  if (modifier & NASM_ATTR_HI20)
1464 	    value = (value >> 12) & 0xfffff;
1465 	  else if (modifier & NASM_ATTR_LO12)
1466 	    value = value & 0xfff;
1467 	  else if (modifier & NASM_ATTR_LO20)
1468 	    value = value & 0xfffff;
1469 	  break;
1470 	default:
1471 	  fprintf (stderr, "Internal error: Don't know how to handle "
1472 			   "parsing results.\n");
1473 	  abort ();
1474 	}
1475     }
1476   else
1477     {
1478       fprintf (stderr, "Internal error: Unknown hardware resource.\n");
1479       abort ();
1480     }
1481 
1482 done:
1483   /* Don't silently discarding bits.  */
1484   if (value & __MASK (fld->shift))
1485     {
1486       pdesc->result = NASM_ERR_OUT_OF_RANGE;
1487       return 0;
1488     }
1489 
1490   /* Check the range of signed or unsigned result.  */
1491   if (fld->hw_res != HW_INT && (value >> (fld->bitsize + fld->shift)))
1492     {
1493       pdesc->result = NASM_ERR_OUT_OF_RANGE;
1494       return 0;
1495     }
1496   else if (fld->hw_res == HW_INT)
1497     {
1498       /* Sign-ext the value.  */
1499       if (((value >> 32) == 0) && (value & 0x80000000))
1500 	value |= (int64_t) -1 << 31;
1501 
1502 
1503       /* Shift the value to positive domain.  */
1504       if ((value + (1 << (fld->bitsize + fld->shift - 1)))
1505 	  >> (fld->bitsize + fld->shift))
1506 	{
1507 	  pdesc->result = NASM_ERR_OUT_OF_RANGE;
1508 	  return 0;
1509 	}
1510     }
1511 
1512   pinsn->insn |= (((value >> fld->shift) & __MASK (fld->bitsize)) << fld->bitpos);
1513   *str = end;
1514   return 1;
1515 }
1516 
1517 /* Try to parse an instruction string based on opcode syntax.  */
1518 
1519 static int
1520 parse_insn (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
1521 	    char *str, struct nds32_opcode *opc)
1522 {
1523   int variant = 0;
1524   char *p = NULL;
1525 
1526   /* A syntax may has optional operands, so we have to try each possible
1527      combination to see if the input is accepted.  In order to do so,
1528      bit-N represent whether optional-operand-N is used in this combination.
1529      That is, if bit-N is set, optional-operand-N is not used.
1530 
1531      For example, there are 2 optional operands in this syntax,
1532 
1533 	"a{,b}{,c}"
1534 
1535      we can try it 4 times (i.e., 1 << 2)
1536 
1537 	0 (b00): "a,b,c"
1538 	1 (b01): "a,c"
1539 	2 (b10): "a,b"
1540 	3 (b11): "a"
1541     */
1542 
1543   /* The outer do-while loop is used to try each possible optional
1544      operand combination, and VARIANT is the bit mask.  The inner loop
1545      iterates each lexeme in the syntax.  */
1546 
1547   do
1548     {
1549       /* OPT is the number of optional operands we've seen.  */
1550       int opt = 0;
1551       lex_t *plex;
1552 
1553       /* PLEX is the syntax iterator and P is the iterator for input
1554 	 string.  */
1555       plex = opc->syntax;
1556       p = str;
1557       /* Initial the base value.  */
1558       pinsn->insn = opc->value;
1559 
1560       while (*plex)
1561 	{
1562 	  if (IS_LEX_CHAR (*plex))
1563 	    {
1564 	      /* If it's a plain char, just compare it.  */
1565 	      if (LEX_CHAR (*plex) != *p)
1566 		{
1567 		  pdesc->result = NASM_ERR_SYNTAX;
1568 		  goto reject;
1569 		}
1570 	      p++;
1571 	    }
1572 	  else if (*plex & SYN_LOPT)
1573 	    {
1574 	      /* If it's '{' and it's not used in this iteration,
1575 		 just skip the whole optional operand.  */
1576 	      if ((1 << (opt++)) & variant)
1577 		{
1578 		  while ((*plex & SYN_ROPT) == 0)
1579 		    plex++;
1580 		}
1581 	    }
1582 	  else if (*plex & SYN_ROPT)
1583 	    {
1584 	      /* ignore */
1585 	    }
1586 	  else
1587 	    {
1588 	      /* If it's a operand, parse the input operand from input.  */
1589 	      if (!parse_operand (pdesc, pinsn, &p, *plex))
1590 		goto reject;
1591 	    }
1592 	  plex++;
1593 	}
1594 
1595       /* Check whether this syntax is accepted.  */
1596       if (*plex == 0 && (*p == '\0' || *p == '!' || *p == '#'))
1597 	return 1;
1598 
1599 reject:
1600       /* If not accepted, try another combination.  */
1601       variant++;
1602     }
1603   while (variant < (1 << opc->variant));
1604 
1605   return 0;
1606 }
1607 
1608 void
1609 nds32_assemble (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
1610 		char *str)
1611 {
1612   struct nds32_opcode *opc;
1613   char *s;
1614   char *mnemoic;
1615   char *dot;
1616   hashval_t hash;
1617 
1618   /* Duplicate the string, so we can modify it for convenience.  */
1619   s = strdup (str);
1620   mnemoic = s;
1621   str = s;
1622 
1623   /* Find opcode mnemoic.  */
1624   while (*s != ' ' && *s != '\t' && *s != '\0')
1625     s++;
1626   if (*s != '\0')
1627     *s++ = '\0';
1628   dot = strchr (mnemoic, '.');
1629 
1630 retry_dot:
1631   /* Lookup the opcode syntax.  */
1632   hash = htab_hash_string (mnemoic);
1633   opc = (struct nds32_opcode *)
1634     htab_find_with_hash (opcode_htab, mnemoic, hash);
1635 
1636   /* If we cannot find a match syntax, try it again without `.'.
1637      For example, try "lmw.adm" first and then try "lmw" again.  */
1638   if (opc == NULL && dot != NULL)
1639     {
1640       *dot = '\0';
1641       s[-1] = ' ';
1642       s = dot + 1;
1643       dot = NULL;
1644       goto retry_dot;
1645     }
1646   else if (opc == NULL)
1647     {
1648       pdesc->result = NASM_ERR_UNKNOWN_OP;
1649       goto out;
1650     }
1651 
1652   /* There may be multiple syntaxes for a given opcode.
1653      Try each one until a match is found.  */
1654   for (; opc; opc = opc->next)
1655     {
1656       /* Build opcode syntax, if it's not been initialized yet.  */
1657       if (opc->syntax == NULL)
1658 	build_opcode_syntax (opc);
1659 
1660       /* Reset status before assemble.  */
1661       pinsn->defuse = opc->defuse;
1662       pinsn->insn = 0;
1663       pinsn->field = NULL;
1664       /* Use opcode attributes to initial instruction attributes.  */
1665       pinsn->attr = opc->attr;
1666       if (parse_insn (pdesc, pinsn, s, opc))
1667 	break;
1668     }
1669 
1670   pinsn->opcode = opc;
1671   if (opc == NULL)
1672     {
1673       pdesc->result = NASM_ERR_SYNTAX;
1674       goto out;
1675     }
1676 
1677   /* A matched opcode is found.  Write the result to instruction buffer.  */
1678   pdesc->result = NASM_OK;
1679 
1680 out:
1681   free (str);
1682 }
1683