83b254760228d84891d0f37ddd30548387feb677
[deliverable/binutils-gdb.git] / opcodes / nds32-asm.c
1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2014 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 }
This page took 0.121659 seconds and 4 git commands to generate.