Add support for Andes NDS32:
[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   {NULL,0 ,0}
862 };
863
864 static const keyword_t keyword_cp[] =
865 {
866   {"cp0", 0, 0}, {"cp1", 1, 0}, {"cp2", 2, 0}, {"cp3", 3, 0}, {NULL, 0, 0}
867 };
868
869 static const keyword_t keyword_cpr[] =
870 {
871   {"cpr0", 0, 0}, {"cpr1", 1, 0}, {"cpr2", 2, 0}, {"cpr3", 3, 0}, {"cpr4", 4, 0},
872   {"cpr5", 5, 0}, {"cpr6", 6, 0}, {"cpr7", 7, 0}, {"cpr8", 8, 0}, {"cpr9", 9, 0},
873   {"cpr10", 10, 0}, {"cpr11", 11, 0}, {"cpr12", 12, 0}, {"cpr13", 13, 0},
874   {"cpr14", 14, 0}, {"cpr15", 15, 0}, {"cpr16", 16, 0}, {"cpr17", 17, 0},
875   {"cpr18", 18, 0}, {"cpr19", 19, 0}, {"cpr20", 20, 0}, {"cpr21", 21, 0},
876   {"cpr22", 22, 0}, {"cpr23", 23, 0}, {"cpr24", 24, 0}, {"cpr25", 25, 0},
877   {"cpr26", 26, 0}, {"cpr27", 27, 0}, {"cpr28", 28, 0}, {"cpr29", 29, 0},
878   {"cpr30", 30, 0}, {"cpr31", 31, 0}, {NULL, 0, 0}
879 };
880
881 static const keyword_t keyword_fsr[] =
882 {
883   {"fs0", 0, 0}, {"fs1", 1, 0}, {"fs2", 2, 0}, {"fs3", 3, 0}, {"fs4", 4, 0},
884   {"fs5", 5, 0}, {"fs6", 6, 0}, {"fs7", 7, 0}, {"fs8", 8, 0}, {"fs9", 9, 0},
885   {"fs10", 10, 0}, {"fs11", 11, 0}, {"fs12", 12, 0}, {"fs13", 13, 0},
886   {"fs14", 14, 0}, {"fs15", 15, 0}, {"fs16", 16, 0}, {"fs17", 17, 0},
887   {"fs18", 18, 0}, {"fs19", 19, 0}, {"fs20", 20, 0}, {"fs21", 21, 0},
888   {"fs22", 22, 0}, {"fs23", 23, 0}, {"fs24", 24, 0}, {"fs25", 25, 0},
889   {"fs26", 26, 0}, {"fs27", 27, 0}, {"fs28", 28, 0}, {"fs29", 29, 0},
890   {"fs30", 30, 0}, {"fs31", 31, 0}, {NULL, 0 ,0}
891 };
892
893 static const keyword_t keyword_fdr[] =
894 {
895   {"fd0", 0, 0}, {"fd1", 1, 0}, {"fd2", 2, 0}, {"fd3", 3, 0}, {"fd4", 4, 0},
896   {"fd5", 5, 0}, {"fd6", 6, 0}, {"fd7", 7, 0}, {"fd8", 8, 0}, {"fd9", 9, 0},
897   {"fd10", 10, 0}, {"fd11", 11, 0}, {"fd12", 12, 0}, {"fd13", 13, 0},
898   {"fd14", 14, 0}, {"fd15", 15, 0}, {"fd16", 16, 0}, {"fd17", 17, 0},
899   {"fd18", 18, 0}, {"fd19", 19, 0}, {"fd20", 20, 0}, {"fd21", 21, 0},
900   {"fd22", 22, 0}, {"fd23", 23, 0}, {"fd24", 24, 0}, {"fd25", 25, 0},
901   {"fd26", 26, 0}, {"fd27", 27, 0}, {"fd28", 28, 0}, {"fd29", 29, 0},
902   {"fd30", 30, 0}, {"fd31", 31, 0}, {NULL, 0, 0}
903 };
904
905 static const keyword_t keyword_abdim[] =
906 {
907   {"bi", 0, 0}, {"bim", 1, 0}, {"bd", 2, 0}, {"bdm", 3, 0},
908   {"ai", 4, 0}, {"aim", 5, 0}, {"ad", 6, 0}, {"adm", 7, 0},
909   {NULL, 0, 0}
910 };
911
912 static const keyword_t keyword_abm[] =
913 {
914   {"b", 0, 0}, {"bm", 1, 0}, {"a", 4, 0}, {"am", 5, 0}, {NULL, 0, 0}
915 };
916
917 static const keyword_t keyword_dtiton[] =
918 {
919   {"iton", 1, 0}, {"ton", 3, 0}, {NULL, 0, 0}
920 };
921
922 static const keyword_t keyword_dtitoff[] =
923 {
924   {"itoff", 1, 0}, {"toff", 3, 0}, {NULL, 0, 0}
925 };
926
927 static const keyword_t keyword_dpref_st[] =
928 {
929   {"srd", 0, 0}, {"mrd", 1, 0}, {"swr", 2, 0}, {"mwr", 3, 0},
930   {"pte", 4, 0}, {"clwr", 5, 0}, {NULL, 0, 0}
931 };
932
933 /* CCTL Ra, SubType */
934 static const keyword_t keyword_cctl_st0[] =
935 {
936   {"l1d_ix_inval", 0X0, 0}, {"l1d_ix_wb", 0X1, 0}, {"l1d_ix_wbinval", 0X2, 0},
937   {"l1d_va_fillck", 0XB, 0}, {"l1d_va_ulck", 0XC, 0}, {"l1i_ix_inval", 0X10, 0},
938   {"l1i_va_fillck", 0X1B, 0}, {"l1i_va_ulck", 0X1C, 0},
939   {NULL, 0, 0}
940 };
941
942 /* CCTL Ra, SubType, level */
943 static const keyword_t keyword_cctl_st1[] =
944 {
945   {"l1d_va_inval", 0X8, 0}, {"l1d_va_wb", 0X9, 0},
946   {"l1d_va_wbinval", 0XA, 0}, {"l1i_va_inval", 0X18, 0},
947   {NULL, 0, 0}
948 };
949
950 /* CCTL Rt, Ra, SubType */
951 static const keyword_t keyword_cctl_st2[] =
952 {
953   {"l1d_ix_rtag", 0X3, 0}, {"l1d_ix_rwd", 0X4, 0},
954   {"l1i_ix_rtag", 0X13, 0}, {"l1i_ix_rwd", 0X14, 0},
955   {NULL, 0, 0}
956 };
957
958 /* CCTL Rb, Ra, SubType */
959 static const keyword_t keyword_cctl_st3[] =
960 {
961   {"l1d_ix_wtag", 0X5, 0}, {"l1d_ix_wwd", 0X6, 0},
962   {"l1i_ix_wtag", 0X15, 0}, {"l1i_ix_wwd", 0X16, 0},
963   {NULL, 0, 0}
964 };
965
966 /* CCTL L1D_INVALALL */
967 static const keyword_t keyword_cctl_st4[] =
968 {
969   {"l1d_invalall", 0x7, 0}, {NULL, 0, 0}
970 };
971
972 /* CCTL L1D_WBALL, level */
973 static const keyword_t keyword_cctl_st5[] =
974 {
975   {"l1d_wball", 0xf, 0}, {NULL, 0, 0}
976 };
977
978 static const keyword_t keyword_cctl_lv[] =
979 {
980   {"1level", 0, 0}, {"alevel", 1, 0}, {"0", 0, 0}, {"1", 1, 0},
981   {NULL, 0, 0},
982 };
983
984 static const keyword_t keyword_tlbop_st[] =
985 {
986   {"trd", 0, 0}, {"targetread", 0, 0},
987   {"twr", 1, 0}, {"targetwrite", 1, 0},
988   {"rwr", 2, 0}, {"rwrite", 2, 0},
989   {"rwlk", 3, 0}, {"rwritelock", 3, 0},
990   {"unlk", 4, 0}, {"unlock", 4, 0},
991   {"inv", 6, 0}, {"invalidate", 6, 0},
992   {NULL, 0, 0},
993   /* "pb" requries two operand and "flua" requires none.  */
994   /* {"pb", 5, 0}, {"probe", 5, 0},
995      {"flua", 7, 0}, {"flushall", 0}, */
996 };
997
998 static const keyword_t keyword_standby_st[] =
999 {
1000   {"no_wake_grant", 0, 0},
1001   {"wake_grant", 1, 0},
1002   {"wait_done", 2, 0},
1003   {"0", 0, 0},
1004   {"1", 1, 0},
1005   {"2", 2, 0},
1006   {"3", 3, 0},
1007   {NULL, 0, 0},
1008 };
1009
1010 static const keyword_t keyword_msync_st[] =
1011 {
1012   {"all", 0, 0}, {"store", 1, 0},
1013   {NULL, 0, 0}
1014 };
1015
1016 \f
1017 /* Hash table for syntax lex.   */
1018 static htab_t field_htab;
1019 /* Hash table for opcodes.  */
1020 static htab_t opcode_htab;
1021 /* Hash table for hardware resources.  */
1022 static htab_t hw_ktabs[_HW_LAST];
1023
1024 static hashval_t
1025 htab_hash_hash (const void *p)
1026 {
1027   struct nds32_hash_entry *h = (struct nds32_hash_entry *) p;
1028
1029   return htab_hash_string (h->name);
1030 }
1031
1032 static int
1033 htab_hash_eq (const void *p, const void *q)
1034 {
1035   struct nds32_hash_entry *h = (struct nds32_hash_entry *) p;
1036   const char *name = (const char *) q;
1037
1038   return strcmp (name, h->name) == 0;
1039 }
1040
1041 \f
1042 /* Build a hash table for array BASE.  Each element is in size of SIZE,
1043    and it's first element is a pointer to the key of string.
1044    It stops inserting elements until reach an NULL key.  */
1045
1046 static htab_t
1047 build_hash_table (const void *base, size_t size)
1048 {
1049   htab_t htab;
1050   hashval_t hash;
1051   const char *p;
1052
1053   htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
1054                             NULL, xcalloc, free);
1055
1056   p = base;
1057   while (1)
1058     {
1059       struct nds32_hash_entry **slot;
1060       struct nds32_hash_entry *h;
1061
1062       h = (struct nds32_hash_entry *) p;
1063
1064       if (h->name == NULL)
1065         break;
1066
1067       hash = htab_hash_string (h->name);
1068       slot = (struct nds32_hash_entry **)
1069         htab_find_slot_with_hash (htab, h->name, hash, INSERT);
1070
1071       assert (slot != NULL && *slot == NULL);
1072
1073       *slot = h;
1074
1075       p = p + size;
1076     }
1077
1078   return htab;
1079 }
1080
1081 /* Build the syntax for a given opcode OPC.  It parses the string
1082    pointed by INSTRUCTION and store the result on SYNTAX, so
1083    when we assemble an instruction, we don't have to parse the syntax
1084    again.  */
1085
1086 static void
1087 build_opcode_syntax (struct nds32_opcode *opc)
1088 {
1089   char odstr[MAX_LEX_LEN];
1090   const char *str;
1091   const char *end;
1092   lex_t *plex;
1093   int len;
1094   hashval_t hash;
1095   field_t *fd;
1096   int opt = 0;
1097
1098   /* Check whether it has been initialized.  */
1099   if (opc->syntax)
1100     return;
1101
1102   opc->syntax = xmalloc (MAX_LEX_NUM * sizeof (lex_t));
1103
1104   str = opc->instruction;
1105   plex = opc->syntax;
1106   while (*str)
1107     {
1108       int fidx;
1109
1110       switch (*str)
1111         {
1112         case '%': *plex = SYN_INPUT; break;
1113         case '=': *plex = SYN_OUTPUT; break;
1114         case '&': *plex = SYN_INPUT | SYN_OUTPUT; break;
1115         case '{':
1116           *plex++ = SYN_LOPT;
1117           opt++;
1118           str++;
1119           continue;
1120         case '}':
1121           *plex++ = SYN_ROPT;
1122           str++;
1123           continue;
1124         default:
1125           *plex++ = *str++;
1126           continue;
1127         }
1128       str++;
1129
1130       /* Extract operand.  */
1131       end = str;
1132       while (ISALNUM (*end) || *end == '_')
1133         end++;
1134       len = end - str;
1135       memcpy (odstr, str, len);
1136       odstr[len] = '\0';
1137
1138       hash = htab_hash_string (odstr);
1139       fd = (field_t *) htab_find_with_hash (field_htab, odstr, hash);
1140       fidx = fd - operand_fields;
1141
1142       if (fd == NULL)
1143         {
1144           fprintf (stderr, "Internal error: Unknown operand, %s\n", str);
1145         }
1146       assert (fd && fidx >= 0 && fidx < (int) ARRAY_SIZE (operand_fields));
1147       *plex |= LEX_SET_FIELD (fidx);
1148
1149       str += len;
1150       plex++;
1151     }
1152
1153   *plex = 0;
1154   opc->variant = opt;
1155   return;
1156
1157   fprintf (stderr, "Unknown lex in assembly syntax, %s.\n", str);
1158   abort ();
1159 }
1160
1161 /* Initialize the assembler.  It must be called before assembling.  */
1162
1163 void
1164 nds32_asm_init (nds32_asm_desc_t *pdesc, int flags)
1165 {
1166   int i;
1167   hashval_t hash;
1168   const keyword_t *keywords[_HW_LAST] =
1169   {
1170     keyword_gpr, keyword_usr, keyword_dxr, keyword_sr, keyword_fsr,
1171     keyword_fdr, keyword_cp, keyword_cpr, keyword_abdim, keyword_abm,
1172     keyword_dtiton, keyword_dtitoff, keyword_dpref_st,
1173     keyword_cctl_st0, keyword_cctl_st1, keyword_cctl_st2,
1174     keyword_cctl_st3, keyword_cctl_st4, keyword_cctl_st5,
1175     keyword_cctl_lv, keyword_tlbop_st, keyword_standby_st,
1176     keyword_msync_st,
1177   };
1178
1179   pdesc->flags = flags;
1180   pdesc->mach = flags & NASM_OPEN_ARCH_MASK;
1181
1182   /* Build keyword tables.  */
1183   field_htab = build_hash_table (operand_fields,
1184                                  sizeof (operand_fields[0]));
1185
1186   for (i = 0; i < _HW_LAST; i++)
1187     hw_ktabs[i] = build_hash_table (keywords[i], sizeof (keyword_t));
1188
1189   /* Build opcode table.  */
1190   opcode_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq,
1191                                    NULL, xcalloc, free);
1192
1193   for (i = 0; i < (int) ARRAY_SIZE (nds32_opcodes); i++)
1194     {
1195       struct nds32_opcode **slot;
1196       struct nds32_opcode *opc;
1197
1198       opc = &nds32_opcodes[i];
1199
1200       hash = htab_hash_string (opc->opcode);
1201       slot = (struct nds32_opcode **)
1202         htab_find_slot_with_hash (opcode_htab, opc->opcode, hash, INSERT);
1203
1204 #define NDS32_PREINIT_SYNTAX
1205 #if defined (NDS32_PREINIT_SYNTAX)
1206       /* Initial SYNTAX when build opcode table, so bug in syntax can be
1207          found when initialized rather than used.  */
1208       build_opcode_syntax (opc);
1209 #endif
1210
1211       if (*slot == NULL)
1212         {
1213           /* This is the new one.  */
1214           *slot = opc;
1215         }
1216       else
1217         {
1218           /* Already exists.  Append to the list.  */
1219           opc = *slot;
1220           while (opc->next)
1221             opc = opc->next;
1222           opc->next = &nds32_opcodes[i];
1223         }
1224     }
1225 }
1226
1227 /* Parse the input and store operand keyword string in ODSTR.
1228    This function is only used for parsing keywords,
1229    HW_INT/HW_UINT are parsed parse_operand callback handler.  */
1230
1231 static char *
1232 parse_to_delimiter (char *str, char odstr[MAX_KEYWORD_LEN])
1233 {
1234   char *outp = odstr;
1235
1236   while (ISALNUM (*str) || *str == '.' || *str == '_')
1237     *outp++ = TOLOWER (*str++);
1238
1239   *outp = '\0';
1240   return str;
1241 }
1242
1243 /* Parse the operand of push25/pop25.  */
1244
1245 static int
1246 parse_re2 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
1247            struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED,
1248            char **pstr, int64_t *value)
1249 {
1250   char *end = *pstr;
1251   char odstr[MAX_KEYWORD_LEN];
1252   keyword_t *k;
1253   hashval_t hash;
1254
1255   if (*end == '$')
1256     end++;
1257   end = parse_to_delimiter (end, odstr);
1258
1259   hash = htab_hash_string (odstr);
1260   k = htab_find_with_hash (hw_ktabs[HW_GPR], odstr, hash);
1261
1262   if (k == NULL)
1263     return NASM_ERR_OPERAND;
1264
1265   if (k->value == 6)
1266     *value = 0;
1267   else if (k->value == 8)
1268     *value = 1;
1269   else if (k->value == 10)
1270     *value = 2;
1271   else if (k->value == 14)
1272     *value = 3;
1273   else
1274     return NASM_ERR_OPERAND;
1275
1276   *pstr = end;
1277   return NASM_R_CONST;
1278 }
1279
1280 /* Parse the operand of lwi45.fe.  */
1281
1282 static int
1283 parse_fe5 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn,
1284            char **pstr, int64_t *value)
1285 {
1286   int r;
1287
1288   r = pdesc->parse_operand (pdesc, pinsn, pstr, value);
1289   if (r != NASM_R_CONST)
1290     return r;
1291
1292   /* 128 == 32 << 2.  Leave the shift to parse_opreand,
1293      so it can check whether it is a multiple of 4.  */
1294   *value = 128 + *value;
1295   return r;
1296 }
1297
1298 /* Parse the operand of movpi45.  */
1299
1300 static int
1301 parse_pi5 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn,
1302            char **pstr, int64_t *value)
1303 {
1304   int r;
1305
1306   r = pdesc->parse_operand (pdesc, pinsn, pstr, value);
1307   if (r != NASM_R_CONST)
1308     return r;
1309
1310   *value -= 16;
1311   return r;
1312 }
1313
1314 /* Generic operand parse base on the information provided by the field.  */
1315
1316 static int
1317 parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
1318                char **str, int syn)
1319 {
1320   char odstr[MAX_KEYWORD_LEN];
1321   char *end;
1322   hashval_t hash;
1323   const field_t *fld = &LEX_GET_FIELD (syn);
1324   keyword_t *k;
1325   int64_t value = 0x100000000;  /* Big enough to overflow.  */
1326   int r;
1327   uint64_t modifier = 0;
1328
1329   end = *str;
1330
1331   if (fld->parse)
1332     {
1333       r = fld->parse (pdesc, pinsn, &end, &value);
1334       goto done;
1335     }
1336
1337   if (fld->hw_res < _HW_LAST)
1338     {
1339       /* Parse the operand in assembly code.  */
1340       if (*end == '$')
1341         end++;
1342       end = parse_to_delimiter (end, odstr);
1343
1344       hash = htab_hash_string (odstr);
1345       k = htab_find_with_hash (hw_ktabs[fld->hw_res], odstr, hash);
1346
1347       if (k == NULL)
1348         {
1349           pdesc->result = NASM_ERR_OPERAND;
1350           return 0;
1351         }
1352
1353       if (fld->hw_res == HW_GPR && (pdesc->flags & NASM_OPEN_REDUCED_REG)
1354           && (k->attr & ATTR (RDREG)) == 0)
1355         {
1356           /* Register not allowed in reduced register.  */
1357           pdesc->result = NASM_ERR_REG_REDUCED;
1358           return 0;
1359         }
1360
1361       if (fld->hw_res == HW_GPR)
1362         {
1363           if (syn & SYN_INPUT)
1364             pinsn->defuse |= USE_REG (k->value);
1365           if (syn & SYN_OUTPUT)
1366             pinsn->defuse |= DEF_REG (k->value);
1367         }
1368
1369       value = k->value;
1370       if (fld->hw_res == HW_GPR && (fld->bitsize + fld->shift) == 4)
1371         value = nds32_r54map[value];
1372     }
1373   else if (fld->hw_res == HW_INT || fld->hw_res == HW_UINT)
1374     {
1375       if (*end == '#')
1376         end++;
1377
1378       /* Handle modifiers.  Do we need to make a table for modifiers?
1379          Do we need to check unknown modifier?  */
1380       if (strncasecmp (end, "hi20(", 5) == 0)
1381         {
1382           modifier |= NASM_ATTR_HI20;
1383           end += 5;
1384         }
1385       else if (strncasecmp (end, "lo12(", 5) == 0)
1386         {
1387           modifier |= NASM_ATTR_LO12;
1388           end += 5;
1389         }
1390       else if (strncasecmp (end, "lo20(", 5) == 0)
1391         {
1392           /* e.g., movi */
1393           modifier |= NASM_ATTR_LO20;
1394           end += 5;
1395         }
1396
1397       r = pdesc->parse_operand (pdesc, pinsn, &end, &value);
1398       if (modifier)
1399         {
1400           /* Consume the ')' of modifier.  */
1401           end++;
1402           pinsn->attr |= modifier;
1403         }
1404
1405       switch (r)
1406         {
1407         case NASM_R_ILLEGAL:
1408           pdesc->result = NASM_ERR_OPERAND;
1409           return 0;
1410         case NASM_R_SYMBOL:
1411           /* This field needs special fix-up.  */
1412           pinsn->field = fld;
1413           break;
1414         case NASM_R_CONST:
1415           if (modifier & NASM_ATTR_HI20)
1416             value = (value >> 12) & 0xfffff;
1417           else if (modifier & NASM_ATTR_LO12)
1418             value = value & 0xfff;
1419           else if (modifier & NASM_ATTR_LO20)
1420             value = value & 0xfffff;
1421           break;
1422         default:
1423           fprintf (stderr, "Internal error: Don't know how to handle "
1424                            "parsing results.\n");
1425           abort ();
1426         }
1427     }
1428   else
1429     {
1430       fprintf (stderr, "Internal error: Unknown hardware resource.\n");
1431       abort ();
1432     }
1433
1434 done:
1435   /* Don't silently discarding bits.  */
1436   if (value & __MASK (fld->shift))
1437     {
1438       pdesc->result = NASM_ERR_OUT_OF_RANGE;
1439       return 0;
1440     }
1441
1442   /* Check the range of signed or unsigned result.  */
1443   if (fld->hw_res != HW_INT && (value >> (fld->bitsize + fld->shift)))
1444     {
1445       pdesc->result = NASM_ERR_OUT_OF_RANGE;
1446       return 0;
1447     }
1448   else if (fld->hw_res == HW_INT)
1449     {
1450       /* Sign-ext the value.  */
1451       if (((value >> 32) == 0) && (value & 0x80000000))
1452         value |= (int64_t) -1 << 31;
1453
1454
1455       /* Shift the value to positive domain.  */
1456       if ((value + (1 << (fld->bitsize + fld->shift - 1)))
1457           >> (fld->bitsize + fld->shift))
1458         {
1459           pdesc->result = NASM_ERR_OUT_OF_RANGE;
1460           return 0;
1461         }
1462     }
1463
1464   pinsn->insn |= (((value >> fld->shift) & __MASK (fld->bitsize)) << fld->bitpos);
1465   *str = end;
1466   return 1;
1467 }
1468
1469 /* Try to parse an instruction string based on opcode syntax.  */
1470
1471 static int
1472 parse_insn (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
1473             char *str, struct nds32_opcode *opc)
1474 {
1475   int variant = 0;
1476   char *p = NULL;
1477
1478   /* A syntax may has optional operands, so we have to try each possible
1479      combination to see if the input is accepted.  In order to do so,
1480      bit-N represent whether optional-operand-N is used in this combination.
1481      That is, if bit-N is set, optional-operand-N is not used.
1482
1483      For example, there are 2 optional operands in this syntax,
1484
1485         "a{,b}{,c}"
1486
1487      we can try it 4 times (i.e., 1 << 2)
1488
1489         0 (b00): "a,b,c"
1490         1 (b01): "a,c"
1491         2 (b10): "a,b"
1492         3 (b11): "a"
1493     */
1494
1495   /* The outer do-while loop is used to try each possible optional
1496      operand combination, and VARIANT is the bit mask.  The inner loop
1497      iterates each lexeme in the syntax.  */
1498
1499   do
1500     {
1501       /* OPT is the number of optional operands we've seen.  */
1502       int opt = 0;
1503       lex_t *plex;
1504
1505       /* PLEX is the syntax iterator and P is the iterator for input
1506          string.  */
1507       plex = opc->syntax;
1508       p = str;
1509       /* Initial the base value.  */
1510       pinsn->insn = opc->value;
1511
1512       while (*plex)
1513         {
1514           if (IS_LEX_CHAR (*plex))
1515             {
1516               /* If it's a plain char, just compare it.  */
1517               if (LEX_CHAR (*plex) != *p)
1518                 {
1519                   pdesc->result = NASM_ERR_SYNTAX;
1520                   goto reject;
1521                 }
1522               p++;
1523             }
1524           else if (*plex & SYN_LOPT)
1525             {
1526               /* If it's '{' and it's not used in this iteration,
1527                  just skip the whole optional operand.  */
1528               if ((1 << (opt++)) & variant)
1529                 {
1530                   while ((*plex & SYN_ROPT) == 0)
1531                     plex++;
1532                 }
1533             }
1534           else if (*plex & SYN_ROPT)
1535             {
1536               /* ignore */
1537             }
1538           else
1539             {
1540               /* If it's a operand, parse the input operand from input.  */
1541               if (!parse_operand (pdesc, pinsn, &p, *plex))
1542                 goto reject;
1543             }
1544           plex++;
1545         }
1546
1547       /* Check whether this syntax is accepted.  */
1548       if (*plex == 0 && (*p == '\0' || *p == '!' || *p == '#'))
1549         return 1;
1550
1551 reject:
1552       /* If not accepted, try another combination.  */
1553       variant++;
1554     }
1555   while (variant < (1 << opc->variant));
1556
1557   return 0;
1558 }
1559
1560 void
1561 nds32_assemble (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn,
1562                 char *str)
1563 {
1564   struct nds32_opcode *opc;
1565   char *s;
1566   char *mnemoic;
1567   char *dot;
1568   hashval_t hash;
1569
1570   /* Duplicate the string, so we can modify it for convenience.  */
1571   s = strdup (str);
1572   mnemoic = s;
1573   str = s;
1574
1575   /* Find opcode mnemoic.  */
1576   while (*s != ' ' && *s != '\t' && *s != '\0')
1577     s++;
1578   if (*s != '\0')
1579     *s++ = '\0';
1580   dot = strchr (mnemoic, '.');
1581
1582 retry_dot:
1583   /* Lookup the opcode syntax.  */
1584   hash = htab_hash_string (mnemoic);
1585   opc = (struct nds32_opcode *)
1586     htab_find_with_hash (opcode_htab, mnemoic, hash);
1587
1588   /* If we cannot find a match syntax, try it again without `.'.
1589      For example, try "lmw.adm" first and then try "lmw" again.  */
1590   if (opc == NULL && dot != NULL)
1591     {
1592       *dot = '\0';
1593       s[-1] = ' ';
1594       s = dot + 1;
1595       dot = NULL;
1596       goto retry_dot;
1597     }
1598   else if (opc == NULL)
1599     {
1600       pdesc->result = NASM_ERR_UNKNOWN_OP;
1601       goto out;
1602     }
1603
1604   /* There may be multiple syntaxes for a given opcode.
1605      Try each one until a match is found.  */
1606   for (; opc; opc = opc->next)
1607     {
1608       /* Build opcode syntax, if it's not been initialized yet.  */
1609       if (opc->syntax == NULL)
1610         build_opcode_syntax (opc);
1611
1612       /* Reset status before assemble.  */
1613       pinsn->defuse = opc->defuse;
1614       pinsn->insn = 0;
1615       pinsn->field = NULL;
1616       /* Use opcode attributes to initial instruction attributes.  */
1617       pinsn->attr = opc->attr;
1618       if (parse_insn (pdesc, pinsn, s, opc))
1619         break;
1620     }
1621
1622   pinsn->opcode = opc;
1623   if (opc == NULL)
1624     {
1625       pdesc->result = NASM_ERR_SYNTAX;
1626       goto out;
1627     }
1628
1629   /* A matched opcode is found.  Write the result to instruction buffer.  */
1630   pdesc->result = NASM_OK;
1631
1632 out:
1633   free (str);
1634 }