Add support for Andes NDS32:
[deliverable/binutils-gdb.git] / opcodes / nds32-asm.c
CommitLineData
35c08157
KLC
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
55static int parse_re2 (struct nds32_asm_desc *, struct nds32_asm_insn *,
56 char **, int64_t *);
57static int parse_fe5 (struct nds32_asm_desc *, struct nds32_asm_insn *,
58 char **, int64_t *);
59static int parse_pi5 (struct nds32_asm_desc *, struct nds32_asm_insn *,
60 char **, int64_t *);
61
62\f
63enum
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
115static 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
214static 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
720static 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
741static 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
773static const keyword_t keyword_dxr[] =
774{
775 {"d0", 0, 0}, {"d1", 1, 0}, {NULL, 0, 0}
776};
777
778static 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
864static const keyword_t keyword_cp[] =
865{
866 {"cp0", 0, 0}, {"cp1", 1, 0}, {"cp2", 2, 0}, {"cp3", 3, 0}, {NULL, 0, 0}
867};
868
869static 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
881static 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
893static 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
905static 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
912static const keyword_t keyword_abm[] =
913{
914 {"b", 0, 0}, {"bm", 1, 0}, {"a", 4, 0}, {"am", 5, 0}, {NULL, 0, 0}
915};
916
917static const keyword_t keyword_dtiton[] =
918{
919 {"iton", 1, 0}, {"ton", 3, 0}, {NULL, 0, 0}
920};
921
922static const keyword_t keyword_dtitoff[] =
923{
924 {"itoff", 1, 0}, {"toff", 3, 0}, {NULL, 0, 0}
925};
926
927static 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 */
934static 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 */
943static 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 */
951static 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 */
959static 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 */
967static const keyword_t keyword_cctl_st4[] =
968{
969 {"l1d_invalall", 0x7, 0}, {NULL, 0, 0}
970};
971
972/* CCTL L1D_WBALL, level */
973static const keyword_t keyword_cctl_st5[] =
974{
975 {"l1d_wball", 0xf, 0}, {NULL, 0, 0}
976};
977
978static 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
984static 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
998static 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
1010static 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. */
1018static htab_t field_htab;
1019/* Hash table for opcodes. */
1020static htab_t opcode_htab;
1021/* Hash table for hardware resources. */
1022static htab_t hw_ktabs[_HW_LAST];
1023
1024static hashval_t
1025htab_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
1032static int
1033htab_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
1046static htab_t
1047build_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
1086static void
1087build_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
1163void
1164nds32_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
1231static char *
1232parse_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
1245static int
1246parse_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
1282static int
1283parse_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
1300static int
1301parse_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
1316static int
1317parse_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
1434done:
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
1471static int
1472parse_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
1551reject:
1552 /* If not accepted, try another combination. */
1553 variant++;
1554 }
1555 while (variant < (1 << opc->variant));
1556
1557 return 0;
1558}
1559
1560void
1561nds32_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
1582retry_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
1632out:
1633 free (str);
1634}
This page took 0.110845 seconds and 4 git commands to generate.