* nds32-asm.c (parse_operand): Fix out-of-range integer constant.
[external/binutils.git] / opcodes / nds32-asm.c
1 /* NDS32-specific support for 32-bit ELF.
2    Copyright (C) 2012-2013 Free Software Foundation, Inc.
3    Contributed by Andes Technology Corporation.
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20    02110-1301, USA.*/
21
22
23 #include <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 \f
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 \f
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 \f
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 \f
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 }