]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/tic80-opc.c
* tic80-opc.c (tic80_symbol_to_value): Changed to accept
[thirdparty/binutils-gdb.git] / opcodes / tic80-opc.c
1 /* Opcode table for TI TMS320C80 (MVP).
2 Copyright 1996 Free Software Foundation, Inc.
3
4 This file is part of GDB, GAS, and the GNU binutils.
5
6 GDB, GAS, and the GNU binutils are free software; you can redistribute
7 them and/or modify them under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either version
9 1, or (at your option) any later version.
10
11 GDB, GAS, and the GNU binutils are distributed in the hope that they
12 will be useful, but WITHOUT ANY WARRANTY; without even the implied
13 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this file; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include <stdio.h>
21 #include "ansidecl.h"
22 #include "opcode/tic80.h"
23
24 /* This file holds various tables for the TMS320C80 (MVP).
25
26 The opcode table is strictly constant data, so the compiler should
27 be able to put it in the .text section.
28
29 This file also holds the operand table. All knowledge about
30 inserting operands into instructions and vice-versa is kept in this
31 file.
32
33 The predefined register table maps from register names to register
34 values. */
35
36 \f
37 /* Table of predefined symbol names, such as general purpose registers,
38 floating point registers, condition codes, control registers, and bit
39 numbers.
40
41 The table is sorted case independently by name so that it is suitable for
42 searching via a binary search using a case independent comparison
43 function.
44
45 Note that the type of the symbol is stored in the upper bits of the value
46 field, which allows the value and type to be passed around as a unit in a
47 single int. The types have to be masked off before using the numeric
48 value as a number.
49 */
50
51 const struct predefined_symbol tic80_predefined_symbols[] =
52 {
53 { "a0", TIC80_OPERAND_FPA | 0 },
54 { "a1", TIC80_OPERAND_FPA | 1 },
55 { "alw.b", TIC80_OPERAND_CC | 7 },
56 { "alw.h", TIC80_OPERAND_CC | 15 },
57 { "alw.w", TIC80_OPERAND_CC | 23 },
58 { "ANASTAT", TIC80_OPERAND_CR | 0x34 },
59 { "BRK1", TIC80_OPERAND_CR | 0x39 },
60 { "BRK2", TIC80_OPERAND_CR | 0x3A },
61 { "CONFIG", TIC80_OPERAND_CR | 2 },
62 { "DLRU", TIC80_OPERAND_CR | 0x500 },
63 { "DTAG0", TIC80_OPERAND_CR | 0x400 },
64 { "DTAG1", TIC80_OPERAND_CR | 0x401 },
65 { "DTAG10", TIC80_OPERAND_CR | 0x40A },
66 { "DTAG11", TIC80_OPERAND_CR | 0x40B },
67 { "DTAG12", TIC80_OPERAND_CR | 0x40C },
68 { "DTAG13", TIC80_OPERAND_CR | 0x40D },
69 { "DTAG14", TIC80_OPERAND_CR | 0x40E },
70 { "DTAG15", TIC80_OPERAND_CR | 0x40F },
71 { "DTAG2", TIC80_OPERAND_CR | 0x402 },
72 { "DTAG3", TIC80_OPERAND_CR | 0x403 },
73 { "DTAG4", TIC80_OPERAND_CR | 0x404 },
74 { "DTAG5", TIC80_OPERAND_CR | 0x405 },
75 { "DTAG6", TIC80_OPERAND_CR | 0x406 },
76 { "DTAG7", TIC80_OPERAND_CR | 0x407 },
77 { "DTAG8", TIC80_OPERAND_CR | 0x408 },
78 { "DTAG9", TIC80_OPERAND_CR | 0x409 },
79 { "ECOMCNTL", TIC80_OPERAND_CR | 0x33 },
80 { "EIP", TIC80_OPERAND_CR | 1 },
81 { "EPC", TIC80_OPERAND_CR | 0 },
82 { "eq.b", TIC80_OPERAND_BITNUM | 0 },
83 { "eq.h", TIC80_OPERAND_BITNUM | 10 },
84 { "eq.w", TIC80_OPERAND_BITNUM | 20 },
85 { "eq0.b", TIC80_OPERAND_CC | 2 },
86 { "eq0.h", TIC80_OPERAND_CC | 10 },
87 { "eq0.w", TIC80_OPERAND_CC | 18 },
88 { "FLTADR", TIC80_OPERAND_CR | 0x11 },
89 { "FLTDTH", TIC80_OPERAND_CR | 0x14 },
90 { "FLTDTL", TIC80_OPERAND_CR | 0x13 },
91 { "FLTOP", TIC80_OPERAND_CR | 0x10 },
92 { "FLTTAG", TIC80_OPERAND_CR | 0x12 },
93 { "FPST", TIC80_OPERAND_CR | 8 },
94 { "ge.b", TIC80_OPERAND_BITNUM | 5 },
95 { "ge.h", TIC80_OPERAND_BITNUM | 15 },
96 { "ge.w", TIC80_OPERAND_BITNUM | 25 },
97 { "ge0.b", TIC80_OPERAND_CC | 3 },
98 { "ge0.h", TIC80_OPERAND_CC | 11 },
99 { "ge0.w", TIC80_OPERAND_CC | 19 },
100 { "gt.b", TIC80_OPERAND_BITNUM | 2 },
101 { "gt.h", TIC80_OPERAND_BITNUM | 12 },
102 { "gt.w", TIC80_OPERAND_BITNUM | 22 },
103 { "gt0.b", TIC80_OPERAND_CC | 1 },
104 { "gt0.h", TIC80_OPERAND_CC | 9 },
105 { "gt0.w", TIC80_OPERAND_CC | 17 },
106 { "hi.b", TIC80_OPERAND_BITNUM | 6 },
107 { "hi.h", TIC80_OPERAND_BITNUM | 16 },
108 { "hi.w", TIC80_OPERAND_BITNUM | 26 },
109 { "hs.b", TIC80_OPERAND_BITNUM | 9 },
110 { "hs.h", TIC80_OPERAND_BITNUM | 19 },
111 { "hs.w", TIC80_OPERAND_BITNUM | 29 },
112 { "IE", TIC80_OPERAND_CR | 6 },
113 { "ILRU", TIC80_OPERAND_CR | 0x300 },
114 { "IN0P", TIC80_OPERAND_CR | 0x4000 },
115 { "IN1P", TIC80_OPERAND_CR | 0x4001 },
116 { "INTPEN", TIC80_OPERAND_CR | 4 },
117 { "ITAG0", TIC80_OPERAND_CR | 0x200 },
118 { "ITAG1", TIC80_OPERAND_CR | 0x201 },
119 { "ITAG10", TIC80_OPERAND_CR | 0x20A },
120 { "ITAG11", TIC80_OPERAND_CR | 0x20B },
121 { "ITAG12", TIC80_OPERAND_CR | 0x20C },
122 { "ITAG13", TIC80_OPERAND_CR | 0x20D },
123 { "ITAG14", TIC80_OPERAND_CR | 0x20E },
124 { "ITAG15", TIC80_OPERAND_CR | 0x20F },
125 { "ITAG2", TIC80_OPERAND_CR | 0x202 },
126 { "ITAG3", TIC80_OPERAND_CR | 0x203 },
127 { "ITAG4", TIC80_OPERAND_CR | 0x204 },
128 { "ITAG5", TIC80_OPERAND_CR | 0x205 },
129 { "ITAG6", TIC80_OPERAND_CR | 0x206 },
130 { "ITAG7", TIC80_OPERAND_CR | 0x207 },
131 { "ITAG8", TIC80_OPERAND_CR | 0x208 },
132 { "ITAG9", TIC80_OPERAND_CR | 0x209 },
133 { "le.b", TIC80_OPERAND_BITNUM | 3 },
134 { "le.h", TIC80_OPERAND_BITNUM | 13 },
135 { "le.w", TIC80_OPERAND_BITNUM | 23 },
136 { "le0.b", TIC80_OPERAND_CC | 6 },
137 { "le0.h", TIC80_OPERAND_CC | 14 },
138 { "le0.w", TIC80_OPERAND_CC | 22 },
139 { "lo.b", TIC80_OPERAND_BITNUM | 8 },
140 { "lo.h", TIC80_OPERAND_BITNUM | 18 },
141 { "lo.w", TIC80_OPERAND_BITNUM | 28 },
142 { "ls.b", TIC80_OPERAND_BITNUM | 7 },
143 { "ls.h", TIC80_OPERAND_BITNUM | 17 },
144 { "ls.w", TIC80_OPERAND_BITNUM | 27 },
145 { "lt.b", TIC80_OPERAND_BITNUM | 4 },
146 { "lt.h", TIC80_OPERAND_BITNUM | 14 },
147 { "lt.w", TIC80_OPERAND_BITNUM | 24 },
148 { "lt0.b", TIC80_OPERAND_CC | 4 },
149 { "lt0.h", TIC80_OPERAND_CC | 12 },
150 { "lt0.w", TIC80_OPERAND_CC | 20 },
151 { "MIP", TIC80_OPERAND_CR | 0x31 },
152 { "MPC", TIC80_OPERAND_CR | 0x30 },
153 { "ne.b", TIC80_OPERAND_BITNUM | 1 },
154 { "ne.h", TIC80_OPERAND_BITNUM | 11 },
155 { "ne.w", TIC80_OPERAND_BITNUM | 21 },
156 { "ne0.b", TIC80_OPERAND_CC | 5 },
157 { "ne0.h", TIC80_OPERAND_CC | 13 },
158 { "ne0.w", TIC80_OPERAND_CC | 21 },
159 { "nev.b", TIC80_OPERAND_CC | 0 },
160 { "nev.h", TIC80_OPERAND_CC | 8 },
161 { "nev.w", TIC80_OPERAND_CC | 16 },
162 { "OUTP", TIC80_OPERAND_CR | 0x4002 },
163 { "PKTREQ", TIC80_OPERAND_CR | 0xD },
164 { "PPERROR", TIC80_OPERAND_CR | 0xA },
165 { "r0", TIC80_OPERAND_GPR | 0 },
166 { "r1", TIC80_OPERAND_GPR | 1 },
167 { "r10", TIC80_OPERAND_GPR | 10 },
168 { "r11", TIC80_OPERAND_GPR | 11 },
169 { "r12", TIC80_OPERAND_GPR | 12 },
170 { "r13", TIC80_OPERAND_GPR | 13 },
171 { "r14", TIC80_OPERAND_GPR | 14 },
172 { "r15", TIC80_OPERAND_GPR | 15 },
173 { "r16", TIC80_OPERAND_GPR | 16 },
174 { "r17", TIC80_OPERAND_GPR | 17 },
175 { "r18", TIC80_OPERAND_GPR | 18 },
176 { "r19", TIC80_OPERAND_GPR | 19 },
177 { "r2", TIC80_OPERAND_GPR | 2 },
178 { "r20", TIC80_OPERAND_GPR | 20 },
179 { "r21", TIC80_OPERAND_GPR | 21 },
180 { "r22", TIC80_OPERAND_GPR | 22 },
181 { "r23", TIC80_OPERAND_GPR | 23 },
182 { "r24", TIC80_OPERAND_GPR | 24 },
183 { "r24", TIC80_OPERAND_GPR | 24 },
184 { "r26", TIC80_OPERAND_GPR | 26 },
185 { "r27", TIC80_OPERAND_GPR | 27 },
186 { "r28", TIC80_OPERAND_GPR | 28 },
187 { "r29", TIC80_OPERAND_GPR | 29 },
188 { "r3", TIC80_OPERAND_GPR | 3 },
189 { "r30", TIC80_OPERAND_GPR | 30 },
190 { "r31", TIC80_OPERAND_GPR | 31 },
191 { "r4", TIC80_OPERAND_GPR | 4 },
192 { "r5", TIC80_OPERAND_GPR | 5 },
193 { "r6", TIC80_OPERAND_GPR | 6 },
194 { "r7", TIC80_OPERAND_GPR | 7 },
195 { "r8", TIC80_OPERAND_GPR | 8 },
196 { "r9", TIC80_OPERAND_GPR | 9 },
197 { "SYSSTK", TIC80_OPERAND_CR | 0x20 },
198 { "SYSTMP", TIC80_OPERAND_CR | 0x21 },
199 { "TCOUNT", TIC80_OPERAND_CR | 0xE },
200 { "TSCALE", TIC80_OPERAND_CR | 0xF },
201 };
202
203 const int tic80_num_predefined_symbols = sizeof (tic80_predefined_symbols) / sizeof (struct predefined_symbol);
204
205 /* This function takes a predefined symbol name in NAME, symbol class
206 in CLASS, and translates it to a numeric value, which it returns.
207
208 If CLASS is zero, any symbol that matches NAME is translated. If
209 CLASS is non-zero, then only a symbol that has class CLASS is
210 matched.
211
212 If no translation is possible, it returns -1, a value not used by
213 any predefined symbol. Note that the predefined symbol array is
214 presorted case independently by name.
215
216 This function is implemented with the assumption that there are no
217 duplicate names in the predefined symbol array, which happens to be
218 true at the moment.
219
220 */
221
222 int
223 tic80_symbol_to_value (name, class)
224 char *name;
225 int class;
226 {
227 const struct predefined_symbol *pdsp;
228 int low = 0;
229 int middle;
230 int high = tic80_num_predefined_symbols - 1;
231 int cmp;
232 int rtnval = -1;
233
234 while (low <= high)
235 {
236 middle = (low + high) / 2;
237 cmp = strcasecmp (name, tic80_predefined_symbols[middle].name);
238 if (cmp < 0)
239 {
240 high = middle - 1;
241 }
242 else if (cmp > 0)
243 {
244 low = middle + 1;
245 }
246 else
247 {
248 pdsp = &tic80_predefined_symbols[middle];
249 if ((class == 0) || (class & pdsp -> value))
250 {
251 rtnval = pdsp -> value;
252 }
253 /* For now we assume that there are no duplicate names */
254 break;
255 }
256 }
257 return (rtnval);
258 }
259
260 /* This function takes a value VAL and finds a matching predefined
261 symbol that is in the operand class specified by CLASS. If CLASS
262 is zero, the first matching symbol is returned. */
263
264 const char *
265 tic80_value_to_symbol (val, class)
266 int val;
267 int class;
268 {
269 const struct predefined_symbol *pdsp;
270 int ival;
271 char *name;
272
273 name = NULL;
274 for (pdsp = tic80_predefined_symbols;
275 pdsp < tic80_predefined_symbols + tic80_num_predefined_symbols;
276 pdsp++)
277 {
278 ival = pdsp -> value & ~TIC80_OPERAND_MASK;
279 if (ival == val)
280 {
281 if ((class == 0) || (class & pdsp -> value))
282 {
283 /* Found the desired match */
284 name = pdsp -> name;
285 break;
286 }
287 }
288 }
289 return (name);
290 }
291
292 \f
293 /* The operands table. The fields are:
294
295 bits, shift, insertion function, extraction function, flags
296 */
297
298 const struct tic80_operand tic80_operands[] =
299 {
300
301 /* The zero index is used to indicate the end of the list of operands. */
302
303 #define UNUSED (0)
304 { 0, 0, 0, 0, 0 },
305
306 /* Short signed immediate value in bits 14-0. */
307
308 #define SSI (UNUSED + 1)
309 { 15, 0, NULL, NULL, TIC80_OPERAND_SIGNED },
310
311 /* Short unsigned immediate value in bits 14-0 */
312
313 #define SUI (SSI + 1)
314 { 15, 0, NULL, NULL, 0 },
315
316 /* Short unsigned bitfield in bits 14-0. We distinguish this
317 from a regular unsigned immediate value only for the convenience
318 of the disassembler and the user. */
319
320 #define SUBF (SUI + 1)
321 { 15, 0, NULL, NULL, TIC80_OPERAND_BITFIELD },
322
323 /* Long signed immediate in following 32 bit word */
324
325 #define LSI (SUBF + 1)
326 { 32, 0, NULL, NULL, TIC80_OPERAND_SIGNED },
327
328 /* Long unsigned immediate in following 32 bit word */
329
330 #define LUI (LSI + 1)
331 { 32, 0, NULL, NULL, 0 },
332
333 /* Long unsigned bitfield in following 32 bit word. We distinguish
334 this from a regular unsigned immediate value only for the
335 convenience of the disassembler and the user. */
336
337 #define LUBF (LUI + 1)
338 { 32, 0, NULL, NULL, TIC80_OPERAND_BITFIELD },
339
340 /* Single precision floating point immediate in following 32 bit
341 word. */
342
343 #define SPFI (LUBF + 1)
344 { 32, 0, NULL, NULL, TIC80_OPERAND_FLOAT },
345
346 /* Register in bits 4-0 */
347
348 #define REG_0 (SPFI + 1)
349 { 5, 0, NULL, NULL, TIC80_OPERAND_GPR },
350
351 /* Even register in bits 4-0 */
352
353 #define REG_0_E (REG_0 + 1)
354 { 5, 0, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_EVEN },
355
356 /* Register in bits 26-22 */
357
358 #define REG_22 (REG_0_E + 1)
359 { 5, 22, NULL, NULL, TIC80_OPERAND_GPR },
360
361 /* Even register in bits 26-22 */
362
363 #define REG_22_E (REG_22 + 1)
364 { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_EVEN },
365
366 /* Register in bits 31-27 */
367
368 #define REG_DEST (REG_22_E + 1)
369 { 5, 27, NULL, NULL, TIC80_OPERAND_GPR },
370
371 /* Even register in bits 31-27 */
372
373 #define REG_DEST_E (REG_DEST + 1)
374 { 5, 27, NULL, NULL, TIC80_OPERAND_GPR + TIC80_OPERAND_EVEN },
375
376 /* Floating point accumulator register (a0-a3) specified by bit 16 (MSB)
377 and bit 11 (LSB) */
378 /* FIXME! Needs to use functions to insert and extract the register
379 number in bits 16 and 11. */
380
381 #define REG_FPA (REG_DEST_E + 1)
382 { 0, 0, NULL, NULL, TIC80_OPERAND_FPA },
383
384 /* Short signed PC word offset in bits 14-0 */
385
386 #define OFF_SS_PC (REG_FPA + 1)
387 { 15, 0, NULL, NULL, TIC80_OPERAND_PCREL | TIC80_OPERAND_SIGNED },
388
389 /* Long signed PC word offset in following 32 bit word */
390
391 #define OFF_SL_PC (OFF_SS_PC + 1)
392 {32, 0, NULL, NULL, TIC80_OPERAND_PCREL | TIC80_OPERAND_SIGNED },
393
394 /* Short signed base relative byte offset in bits 14-0 */
395
396 #define OFF_SS_BR (OFF_SL_PC + 1)
397 { 15, 0, NULL, NULL, TIC80_OPERAND_BASEREL | TIC80_OPERAND_SIGNED },
398
399 /* Long signed base relative byte offset in following 32 bit word */
400
401 #define OFF_SL_BR (OFF_SS_BR + 1)
402 {32, 0, NULL, NULL, TIC80_OPERAND_BASEREL | TIC80_OPERAND_SIGNED },
403
404 /* BITNUM in bits 31-27 */
405
406 #define BITNUM (OFF_SL_BR + 1)
407 { 5, 27, NULL, NULL, TIC80_OPERAND_BITNUM },
408
409 /* Condition code in bits 31-27 */
410
411 #define CC (BITNUM + 1)
412 { 5, 27, NULL, NULL, TIC80_OPERAND_CC },
413
414 /* Control register number in bits 14-0 */
415
416 #define CR_SI (CC + 1)
417 { 15, 0, NULL, NULL, TIC80_OPERAND_CR },
418
419 /* Control register number in next 32 bit word */
420
421 #define CR_LI (CR_SI + 1)
422 { 32, 0, NULL, NULL, TIC80_OPERAND_CR },
423
424 /* A base register in bits 26-22, enclosed in parens */
425
426 #define REG_BASE (CR_LI + 1)
427 { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_PARENS },
428
429 /* A base register in bits 26-22, enclosed in parens, with optional ":m"
430 flag in bit 17 (short immediate instructions only) */
431
432 #define REG_BASE_M_SI (REG_BASE + 1)
433 { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_PARENS | TIC80_OPERAND_M_SI },
434
435 /* A base register in bits 26-22, enclosed in parens, with optional ":m"
436 flag in bit 15 (long immediate and register instructions only) */
437
438 #define REG_BASE_M_LI (REG_BASE_M_SI + 1)
439 { 5, 22, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_PARENS | TIC80_OPERAND_M_LI },
440
441 /* Scaled register in bits 4-0, with optional ":s" modifier flag in bit 11 */
442
443 #define REG_SCALED (REG_BASE_M_LI + 1)
444 { 5, 0, NULL, NULL, TIC80_OPERAND_GPR | TIC80_OPERAND_SCALED },
445
446 /* Long signed immediate in following 32 bit word, with optional ":s" modifier
447 flag in bit 11 */
448
449 #define LSI_SCALED (REG_SCALED + 1)
450 { 32, 0, NULL, NULL, TIC80_OPERAND_SIGNED | TIC80_OPERAND_SCALED },
451
452 /* Unsigned immediate in bits 4-0, used only for shift instructions */
453
454 #define ROTATE (LSI_SCALED + 1)
455 { 5, 0, NULL, NULL, 0 },
456
457 /* Unsigned immediate in bits 9-5, used only for shift instructions */
458 #define ENDMASK (ROTATE + 1)
459 { 5, 5, NULL, NULL, TIC80_OPERAND_ENDMASK },
460
461 };
462
463 const int tic80_num_operands = sizeof (tic80_operands)/sizeof(*tic80_operands);
464
465 \f
466 /* Macros used to generate entries for the opcodes table. */
467
468 #define FIXME 0
469
470 /* Short-Immediate Format Instructions - basic opcode */
471 #define OP_SI(x) (((x) & 0x7F) << 15)
472 #define MASK_SI OP_SI(0x7F)
473
474 /* Long-Immediate Format Instructions - basic opcode */
475 #define OP_LI(x) (((x) & 0x3FF) << 12)
476 #define MASK_LI OP_LI(0x3FF)
477
478 /* Register Format Instructions - basic opcode */
479 #define OP_REG(x) OP_LI(x) /* For readability */
480 #define MASK_REG MASK_LI /* For readability */
481
482 /* The 'n' bit at bit 10 */
483 #define n(x) ((x) << 10)
484
485 /* The 'i' bit at bit 11 */
486 #define i(x) ((x) << 11)
487
488 /* The 'F' bit at bit 27 */
489 #define F(x) ((x) << 27)
490
491 /* The 'E' bit at bit 27 */
492 #define E(x) ((x) << 27)
493
494 /* The 'M' bit at bit 15 in register and long immediate opcodes */
495 #define M_REG(x) ((x) << 15)
496 #define M_LI(x) ((x) << 15)
497
498 /* The 'M' bit at bit 17 in short immediate opcodes */
499 #define M_SI(x) ((x) << 17)
500
501 /* The 'SZ' field at bits 14-13 in register and long immediate opcodes */
502 #define SZ_REG(x) ((x) << 13)
503 #define SZ_LI(x) ((x) << 13)
504
505 /* The 'SZ' field at bits 16-15 in short immediate opcodes */
506 #define SZ_SI(x) ((x) << 15)
507
508 /* The 'D' (direct external memory access) bit at bit 10 in long immediate
509 and register opcodes. */
510 #define D(x) ((x) << 10)
511
512 /* The 'S' (scale offset by data size) bit at bit 11 in long immediate
513 and register opcodes. */
514 #define S(x) ((x) << 11)
515
516 /* The 'PD' field at bits 10-9 in floating point instructions */
517 #define PD(x) ((x) << 9)
518
519 /* The 'P2' field at bits 8-7 in floating point instructions */
520 #define P2(x) ((x) << 7)
521
522 /* The 'P1' field at bits 6-5 in floating point instructions */
523 #define P1(x) ((x) << 5)
524
525 /* The 'a' field at bit 16 in vector instructions */
526 #define V_a1(x) ((x) << 16)
527
528 /* The 'a' field at bit 11 in vector instructions */
529 #define V_a0(x) ((x) << 11)
530
531 /* The 'm' field at bit 10 in vector instructions */
532 #define V_m(x) ((x) << 10)
533
534 /* The 'S' field at bit 9 in vector instructions */
535 #define V_S(x) ((x) << 9)
536
537 /* The 'Z' field at bit 8 in vector instructions */
538 #define V_Z(x) ((x) << 8)
539
540 /* The 'p' field at bit 6 in vector instructions */
541 #define V_p(x) ((x) << 6)
542
543 /* The opcode field at bits 21-17 for vector instructions */
544 #define OP_V(x) ((x) << 17)
545 #define MASK_V OP_V(0x1F)
546
547 \f
548 /* The opcode table. Formatted for better readability on a wide screen. Also, all
549 entries with the same mnemonic are sorted so that they are adjacent in the table,
550 allowing the use of a hash table to locate the first of a sequence of opcodes that have
551 a particular name. */
552
553 const struct tic80_opcode tic80_opcodes[] = {
554
555 /* The "nop" instruction is really "rdcr 0,r0". We put it first so that this
556 specific bit pattern will get disassembled as a nop rather than an rdcr. The
557 mask of all ones ensures that this will happen. */
558
559 {"nop", OP_SI(0x4), ~0, 0, {0} },
560
561 /* The "br" instruction is really "bbz target,r0,31". We put it first so that
562 this specific bit pattern will get disassembled as a br rather than bbz. */
563
564 {"br", OP_LI(0x391), 0xFFFFF000, 0, {OFF_SL_PC} },
565 {"br", OP_REG(0x390), 0xFFFFF000, 0, {REG_0} },
566 {"br", OP_SI(0x48), 0xFFFF8000, 0, {OFF_SS_PC} },
567 {"br.a", OP_LI(0x393), 0xFFFFF000, 0, {OFF_SL_PC} },
568 {"br.a", OP_REG(0x392), 0xFFFFF000, 0, {REG_0} },
569 {"br.a", OP_SI(0x49), 0xFFFF8000, 0, {OFF_SS_PC} },
570
571 /* Signed integer ADD */
572
573 {"add", OP_LI(0x3B1), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
574 {"add", OP_REG(0x3B0), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
575 {"add", OP_SI(0x58), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
576
577 /* Unsigned integer ADD */
578
579 {"addu", OP_LI(0x3B3), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
580 {"addu", OP_REG(0x3B2), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
581 {"addu", OP_SI(0x59), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
582
583 /* Bitwise AND */
584
585 {"and", OP_LI(0x323), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
586 {"and", OP_REG(0x322), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
587 {"and", OP_SI(0x11), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
588 {"and.tt", OP_LI(0x323), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
589 {"and.tt", OP_REG(0x322), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
590 {"and.tt", OP_SI(0x11), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
591
592 /* Bitwise AND with ones complement of both sources */
593
594 {"and.ff", OP_LI(0x331), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
595 {"and.ff", OP_REG(0x330), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
596 {"and.ff", OP_SI(0x18), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
597
598 /* Bitwise AND with ones complement of source 1 */
599
600 {"and.ft", OP_LI(0x329), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
601 {"and.ft", OP_REG(0x328), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
602 {"and.ft", OP_SI(0x14), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
603
604 /* Bitwise AND with ones complement of source 2 */
605
606 {"and.tf", OP_LI(0x325), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
607 {"and.tf", OP_REG(0x324), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
608 {"and.tf", OP_SI(0x12), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
609
610 /* Branch Bit One - nonannulled */
611
612 {"bbo", OP_LI(0x395), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
613 {"bbo", OP_REG(0x394), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
614 {"bbo", OP_SI(0x4A), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
615
616 /* Branch Bit One - annulled */
617
618 {"bbo.a", OP_LI(0x397), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
619 {"bbo.a", OP_REG(0x396), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
620 {"bbo.a", OP_SI(0x4B), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
621
622 /* Branch Bit Zero - nonannulled */
623
624 {"bbz", OP_LI(0x391), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
625 {"bbz", OP_REG(0x390), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
626 {"bbz", OP_SI(0x48), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
627
628 /* Branch Bit Zero - annulled */
629
630 {"bbz.a", OP_LI(0x393), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
631 {"bbz.a", OP_REG(0x392), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
632 {"bbz.a", OP_SI(0x49), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
633
634 /* Branch Conditional - nonannulled */
635
636 {"bcnd", OP_LI(0x399), MASK_LI, 0, {OFF_SL_PC, REG_22, CC} },
637 {"bcnd", OP_REG(0x398), MASK_REG, 0, {REG_0, REG_22, CC} },
638 {"bcnd", OP_SI(0x4C), MASK_SI, 0, {OFF_SS_PC, REG_22, CC} },
639
640 /* Branch Conditional - annulled */
641
642 {"bcnd.a", OP_LI(0x39B), MASK_LI, 0, {OFF_SL_PC, REG_22, CC} },
643 {"bcnd.a", OP_REG(0x39A), MASK_REG, 0, {REG_0, REG_22, CC} },
644 {"bcnd.a", OP_SI(0x4D), MASK_SI, 0, {OFF_SS_PC, REG_22, CC} },
645
646 /* Branch Control Register */
647
648 {"brcr", OP_LI(0x30D), MASK_LI, 0, {CR_LI} },
649 {"brcr", OP_REG(0x30C), MASK_REG, 0, {REG_0} },
650 {"brcr", OP_SI(0x6), MASK_SI, 0, {CR_SI} },
651
652 /* Branch and save return - nonannulled */
653
654 {"bsr", OP_LI(0x381), MASK_LI, 0, {OFF_SL_PC, REG_DEST} },
655 {"bsr", OP_REG(0x380), MASK_REG, 0, {REG_0, REG_DEST} },
656 {"bsr", OP_SI(0x40), MASK_SI, 0, {OFF_SS_PC, REG_DEST} },
657
658 /* Branch and save return - annulled */
659
660 {"bsr.a", OP_LI(0x383), MASK_LI, 0, {OFF_SL_PC, REG_DEST} },
661 {"bsr.a", OP_REG(0x382), MASK_REG, 0, {REG_0, REG_DEST} },
662 {"bsr.a", OP_SI(0x41), MASK_SI, 0, {OFF_SS_PC, REG_DEST} },
663
664 /* Send command */
665
666 {"cmnd", OP_LI(0x305), MASK_LI, 0, {LUI} },
667 {"cmnd", OP_REG(0x304), MASK_REG, 0, {REG_0} },
668 {"cmnd", OP_SI(0x2), MASK_SI, 0, {SUI} },
669
670 /* Integer compare */
671
672 {"cmp", OP_LI(0x3A1), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
673 {"cmp", OP_REG(0x3A0), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
674 {"cmp", OP_SI(0x50), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
675
676 /* Flush data cache subblock - don't clear subblock preset flag */
677
678 {"dcachec", OP_LI(0x371), F(1) | (MASK_LI & ~M_LI(1)) | S(1) | D(1), 0, {LSI, REG_BASE_M_LI} },
679 {"dcachec", OP_REG(0x370), F(1) | (MASK_REG & ~M_REG(1)) | S(1) | D(1), 0, {REG_0, REG_BASE_M_LI} },
680 {"dcachec", OP_SI(0x38), F(1) | (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI} },
681
682 /* Flush data cache subblock - clear subblock preset flag */
683
684 {"dcachef", OP_LI(0x371) | F(1), F(1) | (MASK_LI & ~M_LI(1)) | S(1) | D(1), 0, {LSI, REG_BASE_M_LI} },
685 {"dcachef", OP_REG(0x370) | F(1), F(1) | (MASK_REG & ~M_REG(1)) | S(1) | D(1), 0, {REG_0, REG_BASE_M_LI} },
686 {"dcachef", OP_SI(0x38) | F(1), F(1) | (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI} },
687
688 /* Direct load signed data into register */
689
690 {"dld", OP_LI(0x345) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
691 {"dld", OP_REG(0x344) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
692 {"dld.b", OP_LI(0x341) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
693 {"dld.b", OP_REG(0x340) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
694 {"dld.d", OP_LI(0x347) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
695 {"dld.d", OP_REG(0x346) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
696 {"dld.h", OP_LI(0x343) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
697 {"dld.h", OP_REG(0x342) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
698
699 /* Direct load unsigned data into register */
700
701 {"dld.ub", OP_LI(0x351) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
702 {"dld.ub", OP_REG(0x350) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
703 {"dld.uh", OP_LI(0x353) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
704 {"dld.uh", OP_REG(0x352) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
705
706 /* Direct store data into memory */
707
708 {"dst", OP_LI(0x365) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
709 {"dst", OP_REG(0x364) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
710 {"dst.b", OP_LI(0x361) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
711 {"dst.b", OP_REG(0x360) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
712 {"dst.d", OP_LI(0x367) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
713 {"dst.d", OP_REG(0x366) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
714 {"dst.h", OP_LI(0x363) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
715 {"dst.h", OP_REG(0x362) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
716
717 /* Emulation stop */
718
719 {"estop", OP_LI(0x3FC), MASK_LI, 0, {0} },
720
721 /* Emulation trap */
722
723 {"etrap", OP_LI(0x303) | E(1), MASK_LI | E(1), 0, {LUI} },
724 {"etrap", OP_REG(0x302) | E(1), MASK_REG | E(1), 0, {REG_0} },
725 {"etrap", OP_SI(0x1) | E(1), MASK_SI | E(1), 0, {SUI} },
726
727 /* Floating-point addition */
728
729 {"fadd.ddd", OP_REG(0x3E0) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
730 {"fadd.dsd", OP_REG(0x3E0) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
731 {"fadd.sdd", OP_LI(0x3E1) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
732 {"fadd.sdd", OP_REG(0x3E0) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
733 {"fadd.ssd", OP_LI(0x3E1) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
734 {"fadd.ssd", OP_REG(0x3E0) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
735 {"fadd.sss", OP_LI(0x3E1) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
736 {"fadd.sss", OP_REG(0x3E0) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
737
738 /* Floating point compare */
739
740 {"fcmp.dd", OP_REG(0x3EA) | PD(0) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST} },
741 {"fcmp.ds", OP_REG(0x3EA) | PD(0) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST} },
742 {"fcmp.sd", OP_LI(0x3EB) | PD(0) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST} },
743 {"fcmp.sd", OP_REG(0x3EA) | PD(0) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST} },
744 {"fcmp.ss", OP_LI(0x3EB) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
745 {"fcmp.ss", OP_REG(0x3EA) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
746
747 /* Floating point divide */
748
749 {"fdiv.ddd", OP_REG(0x3E6) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
750 {"fdiv.dsd", OP_REG(0x3E6) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
751 {"fdiv.sdd", OP_LI(0x3E7) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
752 {"fdiv.sdd", OP_REG(0x3E6) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
753 {"fdiv.ssd", OP_LI(0x3E7) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
754 {"fdiv.ssd", OP_REG(0x3E6) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
755 {"fdiv.sss", OP_LI(0x3E7) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
756 {"fdiv.sss", OP_REG(0x3E6) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
757
758 /* Floating point multiply */
759
760 {"fmpy.ddd", OP_REG(0x3E4) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
761 {"fmpy.dsd", OP_REG(0x3E4) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
762 {"fmpy.iii", OP_LI(0x3E5) | PD(2) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_22, REG_DEST} },
763 {"fmpy.iii", OP_REG(0x3E4) | PD(2) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
764 {"fmpy.sdd", OP_LI(0x3E5) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
765 {"fmpy.sdd", OP_REG(0x3E4) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
766 {"fmpy.ssd", OP_LI(0x3E5) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
767 {"fmpy.ssd", OP_REG(0x3E4) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
768 {"fmpy.sss", OP_LI(0x3E5) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
769 {"fmpy.sss", OP_REG(0x3E4) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
770 {"fmpy.uuu", OP_LI(0x3E5) | PD(3) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LUI, REG_22, REG_DEST} },
771 {"fmpy.uuu", OP_REG(0x3E4) | PD(3) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
772
773 /* Convert/Round to Minus Infinity */
774
775 {"frndm.dd", OP_REG(0x3E8) | PD(1) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
776 {"frndm.di", OP_REG(0x3E8) | PD(2) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
777 {"frndm.ds", OP_REG(0x3E8) | PD(0) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
778 {"frndm.du", OP_REG(0x3E8) | PD(3) | P2(3) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
779 {"frndm.id", OP_LI(0x3E9) | PD(1) | P2(3) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
780 {"frndm.id", OP_REG(0x3E8) | PD(1) | P2(3) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
781 {"frndm.is", OP_LI(0x3E9) | PD(0) | P2(3) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
782 {"frndm.is", OP_REG(0x3E8) | PD(0) | P2(3) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
783 {"frndm.sd", OP_LI(0x3E9) | PD(1) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
784 {"frndm.sd", OP_REG(0x3E8) | PD(1) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
785 {"frndm.si", OP_LI(0x3E9) | PD(2) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
786 {"frndm.si", OP_REG(0x3E8) | PD(2) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
787 {"frndm.ss", OP_LI(0x3E9) | PD(0) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
788 {"frndm.ss", OP_REG(0x3E8) | PD(0) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
789 {"frndm.su", OP_LI(0x3E9) | PD(3) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
790 {"frndm.su", OP_REG(0x3E8) | PD(3) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
791 {"frndm.ud", OP_LI(0x3E9) | PD(1) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
792 {"frndm.ud", OP_REG(0x3E8) | PD(1) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
793 {"frndm.us", OP_LI(0x3E9) | PD(0) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
794 {"frndm.us", OP_REG(0x3E8) | PD(0) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
795
796 /* Convert/Round to Nearest */
797
798 {"frndn.dd", OP_REG(0x3E8) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
799 {"frndn.di", OP_REG(0x3E8) | PD(2) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
800 {"frndn.ds", OP_REG(0x3E8) | PD(0) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
801 {"frndn.du", OP_REG(0x3E8) | PD(3) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
802 {"frndn.id", OP_LI(0x3E9) | PD(1) | P2(0) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
803 {"frndn.id", OP_REG(0x3E8) | PD(1) | P2(0) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
804 {"frndn.is", OP_LI(0x3E9) | PD(0) | P2(0) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
805 {"frndn.is", OP_REG(0x3E8) | PD(0) | P2(0) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
806 {"frndn.sd", OP_LI(0x3E9) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
807 {"frndn.sd", OP_REG(0x3E8) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
808 {"frndn.si", OP_LI(0x3E9) | PD(2) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
809 {"frndn.si", OP_REG(0x3E8) | PD(2) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
810 {"frndn.ss", OP_LI(0x3E9) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
811 {"frndn.ss", OP_REG(0x3E8) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
812 {"frndn.su", OP_LI(0x3E9) | PD(3) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
813 {"frndn.su", OP_REG(0x3E8) | PD(3) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
814 {"frndn.ud", OP_LI(0x3E9) | PD(1) | P2(0) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
815 {"frndn.ud", OP_REG(0x3E8) | PD(1) | P2(0) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
816 {"frndn.us", OP_LI(0x3E9) | PD(0) | P2(0) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
817 {"frndn.us", OP_REG(0x3E8) | PD(0) | P2(0) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
818
819 /* Convert/Round to Positive Infinity */
820
821 {"frndp.dd", OP_REG(0x3E8) | PD(1) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
822 {"frndp.di", OP_REG(0x3E8) | PD(2) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
823 {"frndp.ds", OP_REG(0x3E8) | PD(0) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
824 {"frndp.du", OP_REG(0x3E8) | PD(3) | P2(2) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
825 {"frndp.id", OP_LI(0x3E9) | PD(1) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
826 {"frndp.id", OP_REG(0x3E8) | PD(1) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
827 {"frndp.is", OP_LI(0x3E9) | PD(0) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
828 {"frndp.is", OP_REG(0x3E8) | PD(0) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
829 {"frndp.sd", OP_LI(0x3E9) | PD(1) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
830 {"frndp.sd", OP_REG(0x3E8) | PD(1) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
831 {"frndp.si", OP_LI(0x3E9) | PD(2) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
832 {"frndp.si", OP_REG(0x3E8) | PD(2) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
833 {"frndp.ss", OP_LI(0x3E9) | PD(0) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
834 {"frndp.ss", OP_REG(0x3E8) | PD(0) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
835 {"frndp.su", OP_LI(0x3E9) | PD(3) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
836 {"frndp.su", OP_REG(0x3E8) | PD(3) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
837 {"frndp.ud", OP_LI(0x3E9) | PD(1) | P2(2) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
838 {"frndp.ud", OP_REG(0x3E8) | PD(1) | P2(2) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
839 {"frndp.us", OP_LI(0x3E9) | PD(0) | P2(2) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
840 {"frndp.us", OP_REG(0x3E8) | PD(0) | P2(2) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
841
842 /* Convert/Round to Zero */
843
844 {"frndz.dd", OP_REG(0x3E8) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
845 {"frndz.di", OP_REG(0x3E8) | PD(2) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
846 {"frndz.ds", OP_REG(0x3E8) | PD(0) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
847 {"frndz.du", OP_REG(0x3E8) | PD(3) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST} },
848 {"frndz.id", OP_LI(0x3E9) | PD(1) | P2(1) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
849 {"frndz.id", OP_REG(0x3E8) | PD(1) | P2(1) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
850 {"frndz.is", OP_LI(0x3E9) | PD(0) | P2(1) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
851 {"frndz.is", OP_REG(0x3E8) | PD(0) | P2(1) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
852 {"frndz.sd", OP_LI(0x3E9) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
853 {"frndz.sd", OP_REG(0x3E8) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
854 {"frndz.si", OP_LI(0x3E9) | PD(2) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
855 {"frndz.si", OP_REG(0x3E8) | PD(2) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
856 {"frndz.ss", OP_LI(0x3E9) | PD(0) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
857 {"frndz.ss", OP_REG(0x3E8) | PD(0) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
858 {"frndz.su", OP_LI(0x3E9) | PD(3) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
859 {"frndz.su", OP_REG(0x3E8) | PD(3) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
860 {"frndz.ud", OP_LI(0x3E9) | PD(1) | P2(1) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
861 {"frndz.ud", OP_REG(0x3E8) | PD(1) | P2(1) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
862 {"frndz.us", OP_LI(0x3E9) | PD(0) | P2(1) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
863 {"frndz.us", OP_REG(0x3E8) | PD(0) | P2(1) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
864
865 /* Floating point square root */
866
867 {"fsqrt.dd", OP_REG(0x3EE) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_DEST_E} },
868 {"fsqrt.sd", OP_LI(0x3EF) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
869 {"fsqrt.sd", OP_REG(0x3EE) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST_E} },
870 {"fsqrt.ss", OP_LI(0x3EF) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
871 {"fsqrt.ss", OP_REG(0x3EE) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
872
873 /* Floating point subtraction */
874
875 { "fsub.ddd", OP_REG(0x3E2) | PD(1) | P2(1) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22_E, REG_DEST_E} },
876 { "fsub.dsd", OP_REG(0x3E2) | PD(1) | P2(0) | P1(1), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0_E, REG_22, REG_DEST_E} },
877 { "fsub.sdd", OP_LI(0x3E3) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22_E, REG_DEST_E} },
878 { "fsub.sdd", OP_REG(0x3E2) | PD(1) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22_E, REG_DEST_E} },
879 { "fsub.ssd", OP_LI(0x3E3) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST_E} },
880 { "fsub.ssd", OP_REG(0x3E2) | PD(1) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST_E} },
881 { "fsub.sss", OP_LI(0x3E3) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_22, REG_DEST} },
882 { "fsub.sss", OP_REG(0x3E2) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_22, REG_DEST} },
883
884 /* Illegal instructions */
885
886 {"illop0", OP_SI(0x0), MASK_SI, 0, {0} },
887 {"illopF", 0x1FF << 13, 0x1FF << 13, 0, {0} },
888
889 /* Jump and save return */
890
891 {"jsr", OP_LI(0x389), MASK_LI, 0, {OFF_SL_BR, REG_BASE, REG_DEST} },
892 {"jsr", OP_REG(0x388), MASK_REG, 0, {REG_0, REG_BASE, REG_DEST} },
893 {"jsr", OP_SI(0x44), MASK_SI, 0, {OFF_SS_BR, REG_BASE, REG_DEST} },
894 {"jsr.a", OP_LI(0x38B), MASK_LI, 0, {OFF_SL_BR, REG_BASE, REG_DEST} },
895 {"jsr.a", OP_REG(0x38A), MASK_REG, 0, {REG_0, REG_BASE, REG_DEST} },
896 {"jsr.a", OP_SI(0x45), MASK_SI, 0, {OFF_SS_BR, REG_BASE, REG_DEST} },
897
898 /* Load Signed Data Into Register */
899
900 {"ld", OP_LI(0x345) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
901 {"ld", OP_REG(0x344) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
902 {"ld", OP_SI(0x22), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
903 {"ld.b", OP_LI(0x341) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
904 {"ld.b", OP_REG(0x340) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
905 {"ld.b", OP_SI(0x20), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
906 {"ld.d", OP_LI(0x347) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
907 {"ld.d", OP_REG(0x346) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
908 {"ld.d", OP_SI(0x23), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST_E} },
909 {"ld.h", OP_LI(0x343) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
910 {"ld.h", OP_REG(0x342) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
911 {"ld.h", OP_SI(0x21), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
912
913 /* Load Unsigned Data Into Register */
914
915 {"ld.ub", OP_LI(0x351) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
916 {"ld.ub", OP_REG(0x350) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
917 {"ld.ub", OP_SI(0x28), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
918 {"ld.uh", OP_LI(0x353) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
919 {"ld.uh", OP_REG(0x352) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
920 {"ld.uh", OP_SI(0x29), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
921
922 /* Leftmost one */
923
924 {"lmo", OP_LI(0x3F0), MASK_LI, 0, {REG_22, REG_DEST} },
925
926 /* Bitwise logical OR. Note that "or.tt" and "or" are the same instructions. */
927
928 {"or.ff", OP_LI(0x33D), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
929 {"or.ff", OP_REG(0x33C), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
930 {"or.ff", OP_SI(0x1E), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
931 {"or.ft", OP_LI(0x33B), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
932 {"or.ft", OP_REG(0x33A), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
933 {"or.ft", OP_SI(0x1D), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
934 {"or.tf", OP_LI(0x337), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
935 {"or.tf", OP_REG(0x336), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
936 {"or.tf", OP_SI(0x1B), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
937 {"or.tt", OP_LI(0x32F), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
938 {"or.tt", OP_REG(0x32E), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
939 {"or.tt", OP_SI(0x17), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
940 {"or", OP_LI(0x32F), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
941 {"or", OP_REG(0x32E), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
942 {"or", OP_SI(0x17), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
943
944 /* Read Control Register */
945
946 {"rdcr", OP_LI(0x309), MASK_LI | (0x1F << 22), 0, {CR_LI, REG_DEST} },
947 {"rdcr", OP_REG(0x308), MASK_REG | (0x1F << 22), 0, {REG_0, REG_DEST} },
948 {"rdcr", OP_SI(0x4), MASK_SI | (0x1F << 22), 0, {CR_SI, REG_DEST} },
949
950 /* Rightmost one */
951
952 {"rmo", OP_LI(0x3F2), MASK_LI, 0, {REG_22, REG_DEST} },
953
954 /* Shift Register Left - note that rotl, shl, and ins are all alternate names for one of the shift instructions.
955 They appear prior to their sl equivalent so that they will be diassembled as the alternate name. */
956
957
958 {"ins", OP_REG(0x31E) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
959 {"ins", OP_SI(0xF) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
960 {"rotl", OP_REG(0x310) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
961 {"rotl", OP_SI(0x8) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
962 {"shl", OP_REG(0x31C) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
963 {"shl", OP_SI(0xE) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
964 {"sl.dm", OP_REG(0x312) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
965 {"sl.dm", OP_SI(0x9) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
966 {"sl.ds", OP_REG(0x314) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
967 {"sl.ds", OP_SI(0xA) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
968 {"sl.dz", OP_REG(0x310) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
969 {"sl.dz", OP_SI(0x8) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
970 {"sl.em", OP_REG(0x318) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
971 {"sl.em", OP_SI(0xC) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
972 {"sl.es", OP_REG(0x31A) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
973 {"sl.es", OP_SI(0xD) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
974 {"sl.ez", OP_REG(0x316) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
975 {"sl.ez", OP_SI(0xB) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
976 {"sl.im", OP_REG(0x31E) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
977 {"sl.im", OP_SI(0xF) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
978 {"sl.iz", OP_REG(0x31C) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
979 {"sl.iz", OP_SI(0xE) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
980
981 /* Shift Register Left With Inverted Endmask */
982
983 {"sli.dm", OP_REG(0x312) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
984 {"sli.dm", OP_SI(0x9) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
985 {"sli.ds", OP_REG(0x314) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
986 {"sli.ds", OP_SI(0xA) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
987 {"sli.dz", OP_REG(0x310) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
988 {"sli.dz", OP_SI(0x8) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
989 {"sli.em", OP_REG(0x318) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
990 {"sli.em", OP_SI(0xC) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
991 {"sli.es", OP_REG(0x31A) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
992 {"sli.es", OP_SI(0xD) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
993 {"sli.ez", OP_REG(0x316) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
994 {"sli.ez", OP_SI(0xB) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
995 {"sli.im", OP_REG(0x31E) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
996 {"sli.im", OP_SI(0xF) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
997 {"sli.iz", OP_REG(0x31C) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
998 {"sli.iz", OP_SI(0xE) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
999
1000 /* Shift Register Right - note that exts, extu, rotr, sra, and srl are all alternate names for one of the shift instructions.
1001 They appear prior to their sr equivalent so that they will be diassembled as the alternate name. */
1002
1003 {"exts", OP_REG(0x314) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1004 {"exts", OP_SI(0xA) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1005 {"extu", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1006 {"extu", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1007 {"rotr", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1008 {"rotr", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1009 {"sra", OP_REG(0x31A) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1010 {"sra", OP_SI(0xD) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1011 {"srl", OP_REG(0x316) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1012 {"srl", OP_SI(0xB) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1013 {"sr.dm", OP_REG(0x312) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1014 {"sr.dm", OP_SI(0x9) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1015 {"sr.ds", OP_REG(0x314) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1016 {"sr.ds", OP_SI(0xA) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1017 {"sr.dz", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1018 {"sr.dz", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1019 {"sr.em", OP_REG(0x318) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1020 {"sr.em", OP_SI(0xC) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1021 {"sr.es", OP_REG(0x31A) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1022 {"sr.es", OP_SI(0xD) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1023 {"sr.ez", OP_REG(0x316) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1024 {"sr.ez", OP_SI(0xB) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1025 {"sr.im", OP_REG(0x31E) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1026 {"sr.im", OP_SI(0xF) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1027 {"sr.iz", OP_REG(0x31C) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1028 {"sr.iz", OP_SI(0xE) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1029
1030 /* Shift Register Right With Inverted Endmask */
1031
1032 {"sri.dm", OP_REG(0x312) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1033 {"sri.dm", OP_SI(0x9) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1034 {"sri.ds", OP_REG(0x314) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1035 {"sri.ds", OP_SI(0xA) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1036 {"sri.dz", OP_REG(0x310) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1037 {"sri.dz", OP_SI(0x8) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1038 {"sri.em", OP_REG(0x318) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1039 {"sri.em", OP_SI(0xC) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1040 {"sri.es", OP_REG(0x31A) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1041 {"sri.es", OP_SI(0xD) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1042 {"sri.ez", OP_REG(0x316) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1043 {"sri.ez", OP_SI(0xB) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1044 {"sri.im", OP_REG(0x31E) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1045 {"sri.im", OP_SI(0xF) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1046 {"sri.iz", OP_REG(0x31C) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1047 {"sri.iz", OP_SI(0xE) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1048
1049 /* Store Data into Memory */
1050
1051 {"st", OP_LI(0x365) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
1052 {"st", OP_REG(0x364) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
1053 {"st", OP_SI(0x32), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST}},
1054 {"st.b", OP_LI(0x361) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
1055 {"st.b", OP_REG(0x360) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
1056 {"st.b", OP_SI(0x30), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST}},
1057 {"st.d", OP_LI(0x367) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
1058 {"st.d", OP_REG(0x366) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
1059 {"st.d", OP_SI(0x33), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST_E}},
1060 {"st.h", OP_LI(0x363) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
1061 {"st.h", OP_REG(0x362) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
1062 {"st.h", OP_SI(0x31), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST}},
1063
1064 /* Signed Integer Subtract */
1065
1066 {"sub", OP_LI(0x3B5), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
1067 {"sub", OP_REG(0x3B4), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1068 {"sub", OP_SI(0x5A), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
1069
1070 /* Unsigned Integer Subtract */
1071
1072 {"subu", OP_LI(0x3B7), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
1073 {"subu", OP_REG(0x3B6), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1074 {"subu", OP_SI(0x5B), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
1075
1076 /* Write Control Register
1077 Is a special form of the "swcr" instruction so comes before it in the table. */
1078
1079 {"wrcr", OP_LI(0x30B), MASK_LI | (0x1F << 27), 0, {CR_LI, REG_22} },
1080 {"wrcr", OP_REG(0x30A), MASK_REG | (0x1F << 27), 0, {REG_0, REG_22} },
1081 {"wrcr", OP_SI(0x5), MASK_SI | (0x1F << 27), 0, {CR_SI, REG_22} },
1082
1083 /* Swap Control Register */
1084
1085 {"swcr", OP_LI(0x30B), MASK_LI, 0, {CR_LI, REG_22, REG_DEST} },
1086 {"swcr", OP_REG(0x30A), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1087 {"swcr", OP_SI(0x5), MASK_SI, 0, {CR_SI, REG_22, REG_DEST} },
1088
1089 /* Trap */
1090
1091 {"trap", OP_LI(0x303) | E(0), MASK_LI | E(1), 0, {LUI} },
1092 {"trap", OP_REG(0x302) | E(0), MASK_REG | E(1), 0, {REG_0} },
1093 {"trap", OP_SI(0x1) | E(0), MASK_SI | E(1), 0, {SUI} },
1094
1095 /* Vector Floating-Point Add */
1096
1097 {"vadd.dd", OP_REG(0x3C0) | P2(1) | P1(1), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0_E, REG_22_E, REG_22_E} },
1098 {"vadd.sd", OP_LI(0x3C1) | P2(1) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22_E, REG_22_E} },
1099 {"vadd.sd", OP_REG(0x3C0) | P2(1) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E, REG_22_E} },
1100 {"vadd.ss", OP_LI(0x3C1) | P2(0) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22, REG_22} },
1101 {"vadd.ss", OP_REG(0x3C0) | P2(0) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22, REG_22} },
1102
1103 /* Vector Floating-Point Multiply and Add to Accumulator FIXME! This is not yet fully implemented.
1104 From the documentation there appears to be no way to tell the difference between the opcodes for
1105 instructions that have register destinations and instructions that have accumulator destinations.
1106 Further investigation is necessary. Since this isn't critical to getting a TIC80 toolchain up
1107 and running, it is defered until later. */
1108
1109 /* Vector Floating-Point Multiply
1110 Note: If r0 is in the destination reg, then this is a "vector nop" instruction. */
1111
1112 {"vmpy.dd", OP_REG(0x3C4) | P2(1) | P1(1), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {REG_0_E, REG_22_E, REG_22_E} },
1113 {"vmpy.sd", OP_LI(0x3C5) | P2(1) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {SPFI, REG_22_E, REG_22_E} },
1114 {"vmpy.sd", OP_REG(0x3C4) | P2(1) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {REG_0, REG_22_E, REG_22_E} },
1115 {"vmpy.ss", OP_LI(0x3C5) | P2(0) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {SPFI, REG_22, REG_22} },
1116 {"vmpy.ss", OP_REG(0x3C4) | P2(0) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR | TIC80_NO_R0_DEST, {REG_0, REG_22, REG_22} },
1117
1118 /* Vector Floating-Point Multiply and Subtract from Accumulator
1119 FIXME: See note above for vmac instruction */
1120
1121 /* Vector Floating-Point Subtract Accumulator From Source
1122 FIXME: See note above for vmac instruction */
1123
1124 /* Vector Round With Floating-Point Input
1125 FIXME: See note above for vmac instruction */
1126
1127 /* Vector Round with Integer Input */
1128
1129 {"vrnd.id", OP_LI (0x3CB) | P2(1) | P1(0), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LSI, REG_22_E}},
1130 {"vrnd.id", OP_REG (0x3CA) | P2(1) | P1(0), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E}},
1131 {"vrnd.is", OP_LI (0x3CB) | P2(0) | P1(0), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LSI, REG_22}},
1132 {"vrnd.is", OP_REG (0x3CA) | P2(0) | P1(0), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22}},
1133 {"vrnd.ud", OP_LI (0x3CB) | P2(1) | P1(1), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LUI, REG_22_E}},
1134 {"vrnd.ud", OP_REG (0x3CA) | P2(1) | P1(1), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E}},
1135 {"vrnd.us", OP_LI (0x3CB) | P2(0) | P1(1), MASK_LI | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {LUI, REG_22}},
1136 {"vrnd.us", OP_REG (0x3CA) | P2(0) | P1(1), MASK_REG | V_a0(1) | V_Z(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22}},
1137
1138 /* Vector Floating-Point Subtract */
1139
1140 {"vsub.dd", OP_REG(0x3C2) | P2(1) | P1(1), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0_E, REG_22_E, REG_22_E} },
1141 {"vsub.sd", OP_LI(0x3C3) | P2(1) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22_E, REG_22_E} },
1142 {"vsub.sd", OP_REG(0x3C2) | P2(1) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22_E, REG_22_E} },
1143 {"vsub.ss", OP_LI(0x3C3) | P2(0) | P1(0), MASK_LI | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {SPFI, REG_22, REG_22} },
1144 {"vsub.ss", OP_REG(0x3C2) | P2(0) | P1(0), MASK_REG | V_a1(1) | P2(1) | P1(1), TIC80_VECTOR, {REG_0, REG_22, REG_22} },
1145
1146 /* Vector Load Data Into Register - Note that the vector load/store instructions come after the other
1147 vector instructions so that the disassembler will always print the load/store instruction second for
1148 vector instructions that have two instructions in the same opcode. */
1149
1150 {"vld0.d", OP_V(0x1E) | V_m(1) | V_S(1) | V_p(0), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST_E} },
1151 {"vld0.s", OP_V(0x1E) | V_m(1) | V_S(0) | V_p(0), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST} },
1152 {"vld1.d", OP_V(0x1E) | V_m(1) | V_S(1) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST_E} },
1153 {"vld1.s", OP_V(0x1E) | V_m(1) | V_S(0) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST} },
1154
1155 /* Vector Store Data Into Memory - Note that the vector load/store instructions come after the other
1156 vector instructions so that the disassembler will always print the load/store instruction second for
1157 vector instructions that have two instructions in the same opcode. */
1158
1159 {"vst.d", OP_V(0x1E) | V_m(0) | V_S(1) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST_E} },
1160 {"vst.s", OP_V(0x1E) | V_m(0) | V_S(0) | V_p(1), MASK_V | V_m(1) | V_S(1) | V_p(1), TIC80_VECTOR, {REG_DEST} },
1161
1162 {"xnor", OP_LI(0x333), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
1163 {"xnor", OP_REG(0x332), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1164 {"xnor", OP_SI(0x19), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
1165
1166 {"xor", OP_LI(0x32D), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
1167 {"xor", OP_REG(0x32C), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1168 {"xor", OP_SI(0x16), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
1169
1170 };
1171
1172 const int tic80_num_opcodes = sizeof (tic80_opcodes) / sizeof (tic80_opcodes[0]);