]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/tic80-opc.c
* tic80-opc.c (tic80_operands): Fix typo '+' -> '|'.
[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. The short immediate forms also come before the long immediate forms
552 so that the assembler will pick the "best fit" for the size of the operand. */
553
554 const struct tic80_opcode tic80_opcodes[] = {
555
556 /* The "nop" instruction is really "rdcr 0,r0". We put it first so that this
557 specific bit pattern will get disassembled as a nop rather than an rdcr. The
558 mask of all ones ensures that this will happen. */
559
560 {"nop", OP_SI(0x4), ~0, 0, {0} },
561
562 /* The "br" instruction is really "bbz target,r0,31". We put it first so that
563 this specific bit pattern will get disassembled as a br rather than bbz. */
564
565 {"br", OP_SI(0x48), 0xFFFF8000, 0, {OFF_SS_PC} },
566 {"br", OP_LI(0x391), 0xFFFFF000, 0, {OFF_SL_PC} },
567 {"br", OP_REG(0x390), 0xFFFFF000, 0, {REG_0} },
568 {"br.a", OP_SI(0x49), 0xFFFF8000, 0, {OFF_SS_PC} },
569 {"br.a", OP_LI(0x393), 0xFFFFF000, 0, {OFF_SL_PC} },
570 {"br.a", OP_REG(0x392), 0xFFFFF000, 0, {REG_0} },
571
572 /* Signed integer ADD */
573
574 {"add", OP_SI(0x58), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
575 {"add", OP_LI(0x3B1), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
576 {"add", OP_REG(0x3B0), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
577
578 /* Unsigned integer ADD */
579
580 {"addu", OP_SI(0x59), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
581 {"addu", OP_LI(0x3B3), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
582 {"addu", OP_REG(0x3B2), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
583
584 /* Bitwise AND */
585
586 {"and", OP_SI(0x11), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
587 {"and", OP_LI(0x323), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
588 {"and", OP_REG(0x322), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
589 {"and.tt", OP_SI(0x11), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
590 {"and.tt", OP_LI(0x323), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
591 {"and.tt", OP_REG(0x322), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
592
593 /* Bitwise AND with ones complement of both sources */
594
595 {"and.ff", OP_SI(0x18), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
596 {"and.ff", OP_LI(0x331), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
597 {"and.ff", OP_REG(0x330), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
598
599 /* Bitwise AND with ones complement of source 1 */
600
601 {"and.ft", OP_SI(0x14), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
602 {"and.ft", OP_LI(0x329), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
603 {"and.ft", OP_REG(0x328), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
604
605 /* Bitwise AND with ones complement of source 2 */
606
607 {"and.tf", OP_SI(0x12), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
608 {"and.tf", OP_LI(0x325), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
609 {"and.tf", OP_REG(0x324), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
610
611 /* Branch Bit One - nonannulled */
612
613 {"bbo", OP_SI(0x4A), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
614 {"bbo", OP_LI(0x395), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
615 {"bbo", OP_REG(0x394), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
616
617 /* Branch Bit One - annulled */
618
619 {"bbo.a", OP_SI(0x4B), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
620 {"bbo.a", OP_LI(0x397), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
621 {"bbo.a", OP_REG(0x396), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
622
623 /* Branch Bit Zero - nonannulled */
624
625 {"bbz", OP_SI(0x48), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
626 {"bbz", OP_LI(0x391), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
627 {"bbz", OP_REG(0x390), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
628
629 /* Branch Bit Zero - annulled */
630
631 {"bbz.a", OP_SI(0x49), MASK_SI, 0, {OFF_SS_PC, REG_22, BITNUM} },
632 {"bbz.a", OP_LI(0x393), MASK_LI, 0, {OFF_SL_PC, REG_22, BITNUM} },
633 {"bbz.a", OP_REG(0x392), MASK_REG, 0, {REG_0, REG_22, BITNUM} },
634
635 /* Branch Conditional - nonannulled */
636
637 {"bcnd", OP_SI(0x4C), MASK_SI, 0, {OFF_SS_PC, REG_22, CC} },
638 {"bcnd", OP_LI(0x399), MASK_LI, 0, {OFF_SL_PC, REG_22, CC} },
639 {"bcnd", OP_REG(0x398), MASK_REG, 0, {REG_0, REG_22, CC} },
640
641 /* Branch Conditional - annulled */
642
643 {"bcnd.a", OP_SI(0x4D), MASK_SI, 0, {OFF_SS_PC, REG_22, CC} },
644 {"bcnd.a", OP_LI(0x39B), MASK_LI, 0, {OFF_SL_PC, REG_22, CC} },
645 {"bcnd.a", OP_REG(0x39A), MASK_REG, 0, {REG_0, REG_22, CC} },
646
647 /* Branch Control Register */
648
649 {"brcr", OP_SI(0x6), MASK_SI, 0, {CR_SI} },
650 {"brcr", OP_LI(0x30D), MASK_LI, 0, {CR_LI} },
651 {"brcr", OP_REG(0x30C), MASK_REG, 0, {REG_0} },
652
653 /* Branch and save return - nonannulled */
654
655 {"bsr", OP_SI(0x40), MASK_SI, 0, {OFF_SS_PC, REG_DEST} },
656 {"bsr", OP_LI(0x381), MASK_LI, 0, {OFF_SL_PC, REG_DEST} },
657 {"bsr", OP_REG(0x380), MASK_REG, 0, {REG_0, REG_DEST} },
658
659 /* Branch and save return - annulled */
660
661 {"bsr.a", OP_SI(0x41), MASK_SI, 0, {OFF_SS_PC, REG_DEST} },
662 {"bsr.a", OP_LI(0x383), MASK_LI, 0, {OFF_SL_PC, REG_DEST} },
663 {"bsr.a", OP_REG(0x382), MASK_REG, 0, {REG_0, REG_DEST} },
664
665 /* Send command */
666
667 {"cmnd", OP_SI(0x2), MASK_SI, 0, {SUI} },
668 {"cmnd", OP_LI(0x305), MASK_LI, 0, {LUI} },
669 {"cmnd", OP_REG(0x304), MASK_REG, 0, {REG_0} },
670
671 /* Integer compare */
672
673 {"cmp", OP_SI(0x50), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
674 {"cmp", OP_LI(0x3A1), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
675 {"cmp", OP_REG(0x3A0), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
676
677 /* Flush data cache subblock - don't clear subblock preset flag */
678
679 {"dcachec", OP_SI(0x38), F(1) | (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI} },
680 {"dcachec", OP_LI(0x371), F(1) | (MASK_LI & ~M_LI(1)) | S(1) | D(1), 0, {LSI, REG_BASE_M_LI} },
681 {"dcachec", OP_REG(0x370), F(1) | (MASK_REG & ~M_REG(1)) | S(1) | D(1), 0, {REG_0, REG_BASE_M_LI} },
682
683 /* Flush data cache subblock - clear subblock preset flag */
684
685 {"dcachef", OP_SI(0x38) | F(1), F(1) | (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI} },
686 {"dcachef", OP_LI(0x371) | F(1), F(1) | (MASK_LI & ~M_LI(1)) | S(1) | D(1), 0, {LSI, REG_BASE_M_LI} },
687 {"dcachef", OP_REG(0x370) | F(1), F(1) | (MASK_REG & ~M_REG(1)) | S(1) | D(1), 0, {REG_0, REG_BASE_M_LI} },
688
689 /* Direct load signed data into register */
690
691 {"dld", OP_LI(0x345) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
692 {"dld", OP_REG(0x344) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
693 {"dld.b", OP_LI(0x341) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
694 {"dld.b", OP_REG(0x340) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
695 {"dld.d", OP_LI(0x347) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
696 {"dld.d", OP_REG(0x346) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
697 {"dld.h", OP_LI(0x343) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
698 {"dld.h", OP_REG(0x342) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
699
700 /* Direct load unsigned data into register */
701
702 {"dld.ub", OP_LI(0x351) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
703 {"dld.ub", OP_REG(0x350) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
704 {"dld.uh", OP_LI(0x353) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
705 {"dld.uh", OP_REG(0x352) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
706
707 /* Direct store data into memory */
708
709 {"dst", OP_LI(0x365) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
710 {"dst", OP_REG(0x364) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
711 {"dst.b", OP_LI(0x361) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
712 {"dst.b", OP_REG(0x360) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
713 {"dst.d", OP_LI(0x367) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
714 {"dst.d", OP_REG(0x366) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
715 {"dst.h", OP_LI(0x363) | D(1), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
716 {"dst.h", OP_REG(0x362) | D(1), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
717
718 /* Emulation stop */
719
720 {"estop", OP_LI(0x3FC), MASK_LI, 0, {0} },
721
722 /* Emulation trap */
723
724 {"etrap", OP_SI(0x1) | E(1), MASK_SI | E(1), 0, {SUI} },
725 {"etrap", OP_LI(0x303) | E(1), MASK_LI | E(1), 0, {LUI} },
726 {"etrap", OP_REG(0x302) | E(1), MASK_REG | E(1), 0, {REG_0} },
727
728 /* Floating-point addition */
729
730 {"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} },
731 {"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} },
732 {"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} },
733 {"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} },
734 {"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} },
735 {"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} },
736 {"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} },
737 {"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} },
738
739 /* Floating point compare */
740
741 {"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} },
742 {"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} },
743 {"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} },
744 {"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} },
745 {"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} },
746 {"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} },
747
748 /* Floating point divide */
749
750 {"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} },
751 {"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} },
752 {"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} },
753 {"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} },
754 {"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} },
755 {"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} },
756 {"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} },
757 {"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} },
758
759 /* Floating point multiply */
760
761 {"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} },
762 {"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} },
763 {"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} },
764 {"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} },
765 {"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} },
766 {"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} },
767 {"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} },
768 {"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} },
769 {"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} },
770 {"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} },
771 {"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} },
772 {"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} },
773
774 /* Convert/Round to Minus Infinity */
775
776 {"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} },
777 {"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} },
778 {"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} },
779 {"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} },
780 {"frndm.id", OP_LI(0x3E9) | PD(1) | P2(3) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
781 {"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} },
782 {"frndm.is", OP_LI(0x3E9) | PD(0) | P2(3) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
783 {"frndm.is", OP_REG(0x3E8) | PD(0) | P2(3) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
784 {"frndm.sd", OP_LI(0x3E9) | PD(1) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
785 {"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} },
786 {"frndm.si", OP_LI(0x3E9) | PD(2) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
787 {"frndm.si", OP_REG(0x3E8) | PD(2) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
788 {"frndm.ss", OP_LI(0x3E9) | PD(0) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
789 {"frndm.ss", OP_REG(0x3E8) | PD(0) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
790 {"frndm.su", OP_LI(0x3E9) | PD(3) | P2(3) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
791 {"frndm.su", OP_REG(0x3E8) | PD(3) | P2(3) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
792 {"frndm.ud", OP_LI(0x3E9) | PD(1) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
793 {"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} },
794 {"frndm.us", OP_LI(0x3E9) | PD(0) | P2(3) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
795 {"frndm.us", OP_REG(0x3E8) | PD(0) | P2(3) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
796
797 /* Convert/Round to Nearest */
798
799 {"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} },
800 {"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} },
801 {"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} },
802 {"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} },
803 {"frndn.id", OP_LI(0x3E9) | PD(1) | P2(0) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
804 {"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} },
805 {"frndn.is", OP_LI(0x3E9) | PD(0) | P2(0) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
806 {"frndn.is", OP_REG(0x3E8) | PD(0) | P2(0) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
807 {"frndn.sd", OP_LI(0x3E9) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
808 {"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} },
809 {"frndn.si", OP_LI(0x3E9) | PD(2) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
810 {"frndn.si", OP_REG(0x3E8) | PD(2) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
811 {"frndn.ss", OP_LI(0x3E9) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
812 {"frndn.ss", OP_REG(0x3E8) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
813 {"frndn.su", OP_LI(0x3E9) | PD(3) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
814 {"frndn.su", OP_REG(0x3E8) | PD(3) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
815 {"frndn.ud", OP_LI(0x3E9) | PD(1) | P2(0) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
816 {"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} },
817 {"frndn.us", OP_LI(0x3E9) | PD(0) | P2(0) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
818 {"frndn.us", OP_REG(0x3E8) | PD(0) | P2(0) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
819
820 /* Convert/Round to Positive Infinity */
821
822 {"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} },
823 {"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} },
824 {"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} },
825 {"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} },
826 {"frndp.id", OP_LI(0x3E9) | PD(1) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
827 {"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} },
828 {"frndp.is", OP_LI(0x3E9) | PD(0) | P2(2) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
829 {"frndp.is", OP_REG(0x3E8) | PD(0) | P2(2) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
830 {"frndp.sd", OP_LI(0x3E9) | PD(1) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
831 {"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} },
832 {"frndp.si", OP_LI(0x3E9) | PD(2) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
833 {"frndp.si", OP_REG(0x3E8) | PD(2) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
834 {"frndp.ss", OP_LI(0x3E9) | PD(0) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
835 {"frndp.ss", OP_REG(0x3E8) | PD(0) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
836 {"frndp.su", OP_LI(0x3E9) | PD(3) | P2(2) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
837 {"frndp.su", OP_REG(0x3E8) | PD(3) | P2(2) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
838 {"frndp.ud", OP_LI(0x3E9) | PD(1) | P2(2) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
839 {"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} },
840 {"frndp.us", OP_LI(0x3E9) | PD(0) | P2(2) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
841 {"frndp.us", OP_REG(0x3E8) | PD(0) | P2(2) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
842
843 /* Convert/Round to Zero */
844
845 {"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} },
846 {"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} },
847 {"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} },
848 {"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} },
849 {"frndz.id", OP_LI(0x3E9) | PD(1) | P2(1) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
850 {"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} },
851 {"frndz.is", OP_LI(0x3E9) | PD(0) | P2(1) | P1(2), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
852 {"frndz.is", OP_REG(0x3E8) | PD(0) | P2(1) | P1(2), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
853 {"frndz.sd", OP_LI(0x3E9) | PD(1) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
854 {"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} },
855 {"frndz.si", OP_LI(0x3E9) | PD(2) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
856 {"frndz.si", OP_REG(0x3E8) | PD(2) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
857 {"frndz.ss", OP_LI(0x3E9) | PD(0) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
858 {"frndz.ss", OP_REG(0x3E8) | PD(0) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
859 {"frndz.su", OP_LI(0x3E9) | PD(3) | P2(1) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
860 {"frndz.su", OP_REG(0x3E8) | PD(3) | P2(1) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
861 {"frndz.ud", OP_LI(0x3E9) | PD(1) | P2(1) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST_E} },
862 {"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} },
863 {"frndz.us", OP_LI(0x3E9) | PD(0) | P2(1) | P1(3), MASK_LI | PD(3) | P2(3) | P1(3), 0, {LSI, REG_DEST} },
864 {"frndz.us", OP_REG(0x3E8) | PD(0) | P2(1) | P1(3), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
865
866 /* Floating point square root */
867
868 {"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} },
869 {"fsqrt.sd", OP_LI(0x3EF) | PD(1) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST_E} },
870 {"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} },
871 {"fsqrt.ss", OP_LI(0x3EF) | PD(0) | P2(0) | P1(0), MASK_LI | PD(3) | P2(3) | P1(3), 0, {SPFI, REG_DEST} },
872 {"fsqrt.ss", OP_REG(0x3EE) | PD(0) | P2(0) | P1(0), MASK_REG | PD(3) | P2(3) | P1(3), 0, {REG_0, REG_DEST} },
873
874 /* Floating point subtraction */
875
876 { "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} },
877 { "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} },
878 { "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} },
879 { "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} },
880 { "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} },
881 { "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} },
882 { "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} },
883 { "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} },
884
885 /* Illegal instructions */
886
887 {"illop0", OP_SI(0x0), MASK_SI, 0, {0} },
888 {"illopF", 0x1FF << 13, 0x1FF << 13, 0, {0} },
889
890 /* Jump and save return */
891
892 {"jsr", OP_SI(0x44), MASK_SI, 0, {OFF_SS_BR, REG_BASE, REG_DEST} },
893 {"jsr", OP_LI(0x389), MASK_LI, 0, {OFF_SL_BR, REG_BASE, REG_DEST} },
894 {"jsr", OP_REG(0x388), MASK_REG, 0, {REG_0, REG_BASE, REG_DEST} },
895 {"jsr.a", OP_SI(0x45), MASK_SI, 0, {OFF_SS_BR, REG_BASE, REG_DEST} },
896 {"jsr.a", OP_LI(0x38B), MASK_LI, 0, {OFF_SL_BR, REG_BASE, REG_DEST} },
897 {"jsr.a", OP_REG(0x38A), MASK_REG, 0, {REG_0, REG_BASE, REG_DEST} },
898
899 /* Load Signed Data Into Register */
900
901 {"ld", OP_SI(0x22), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
902 {"ld", OP_LI(0x345) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
903 {"ld", OP_REG(0x344) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
904 {"ld.b", OP_SI(0x20), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
905 {"ld.b", OP_LI(0x341) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
906 {"ld.b", OP_REG(0x340) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
907 {"ld.d", OP_SI(0x23), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST_E} },
908 {"ld.d", OP_LI(0x347) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
909 {"ld.d", OP_REG(0x346) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
910 {"ld.h", OP_SI(0x21), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
911 {"ld.h", OP_LI(0x343) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
912 {"ld.h", OP_REG(0x342) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
913
914 /* Load Unsigned Data Into Register */
915
916 {"ld.ub", OP_SI(0x28), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
917 {"ld.ub", OP_LI(0x351) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
918 {"ld.ub", OP_REG(0x350) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
919 {"ld.uh", OP_SI(0x29), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST} },
920 {"ld.uh", OP_LI(0x353) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
921 {"ld.uh", OP_REG(0x352) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
922
923 /* Leftmost one */
924
925 {"lmo", OP_LI(0x3F0), MASK_LI, 0, {REG_22, REG_DEST} },
926
927 /* Bitwise logical OR. Note that "or.tt" and "or" are the same instructions. */
928
929 {"or.ff", OP_SI(0x1E), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
930 {"or.ff", OP_LI(0x33D), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
931 {"or.ff", OP_REG(0x33C), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
932 {"or.ft", OP_SI(0x1D), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
933 {"or.ft", OP_LI(0x33B), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
934 {"or.ft", OP_REG(0x33A), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
935 {"or.tf", OP_SI(0x1B), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
936 {"or.tf", OP_LI(0x337), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
937 {"or.tf", OP_REG(0x336), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
938 {"or.tt", OP_SI(0x17), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
939 {"or.tt", OP_LI(0x32F), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
940 {"or.tt", OP_REG(0x32E), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
941 {"or", OP_SI(0x17), MASK_SI, 0, {SUI, REG_22, REG_DEST} },
942 {"or", OP_LI(0x32F), MASK_LI, 0, {LUI, REG_22, REG_DEST} },
943 {"or", OP_REG(0x32E), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
944
945 /* Read Control Register */
946
947 {"rdcr", OP_SI(0x4), MASK_SI | (0x1F << 22), 0, {CR_SI, REG_DEST} },
948 {"rdcr", OP_LI(0x309), MASK_LI | (0x1F << 22), 0, {CR_LI, REG_DEST} },
949 {"rdcr", OP_REG(0x308), MASK_REG | (0x1F << 22), 0, {REG_0, REG_DEST} },
950
951 /* Rightmost one */
952
953 {"rmo", OP_LI(0x3F2), MASK_LI, 0, {REG_22, REG_DEST} },
954
955 /* Shift Register Left - note that rotl, shl, and ins are all alternate names for one of the shift instructions.
956 They appear prior to their sl equivalent so that they will be diassembled as the alternate name. */
957
958
959 {"ins", OP_REG(0x31E) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
960 {"ins", OP_SI(0xF) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
961 {"rotl", OP_REG(0x310) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
962 {"rotl", OP_SI(0x8) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
963 {"shl", OP_REG(0x31C) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
964 {"shl", OP_SI(0xE) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
965 {"sl.dm", OP_REG(0x312) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
966 {"sl.dm", OP_SI(0x9) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
967 {"sl.ds", OP_REG(0x314) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
968 {"sl.ds", OP_SI(0xA) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
969 {"sl.dz", OP_REG(0x310) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
970 {"sl.dz", OP_SI(0x8) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
971 {"sl.em", OP_REG(0x318) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
972 {"sl.em", OP_SI(0xC) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
973 {"sl.es", OP_REG(0x31A) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
974 {"sl.es", OP_SI(0xD) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
975 {"sl.ez", OP_REG(0x316) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
976 {"sl.ez", OP_SI(0xB) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
977 {"sl.im", OP_REG(0x31E) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
978 {"sl.im", OP_SI(0xF) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
979 {"sl.iz", OP_REG(0x31C) | i(0) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
980 {"sl.iz", OP_SI(0xE) | i(0) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
981
982 /* Shift Register Left With Inverted Endmask */
983
984 {"sli.dm", OP_REG(0x312) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
985 {"sli.dm", OP_SI(0x9) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
986 {"sli.ds", OP_REG(0x314) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
987 {"sli.ds", OP_SI(0xA) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
988 {"sli.dz", OP_REG(0x310) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
989 {"sli.dz", OP_SI(0x8) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
990 {"sli.em", OP_REG(0x318) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
991 {"sli.em", OP_SI(0xC) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
992 {"sli.es", OP_REG(0x31A) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
993 {"sli.es", OP_SI(0xD) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
994 {"sli.ez", OP_REG(0x316) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
995 {"sli.ez", OP_SI(0xB) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
996 {"sli.im", OP_REG(0x31E) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
997 {"sli.im", OP_SI(0xF) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
998 {"sli.iz", OP_REG(0x31C) | i(1) | n(0), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
999 {"sli.iz", OP_SI(0xE) | i(1) | n(0), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1000
1001 /* Shift Register Right - note that exts, extu, rotr, sra, and srl are all alternate names for one of the shift instructions.
1002 They appear prior to their sr equivalent so that they will be diassembled as the alternate name. */
1003
1004 {"exts", OP_REG(0x314) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1005 {"exts", OP_SI(0xA) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1006 {"extu", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1007 {"extu", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1008 {"rotr", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1009 {"rotr", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1010 {"sra", OP_REG(0x31A) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1011 {"sra", OP_SI(0xD) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1012 {"srl", OP_REG(0x316) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1013 {"srl", OP_SI(0xB) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1014 {"sr.dm", OP_REG(0x312) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1015 {"sr.dm", OP_SI(0x9) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1016 {"sr.ds", OP_REG(0x314) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1017 {"sr.ds", OP_SI(0xA) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1018 {"sr.dz", OP_REG(0x310) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1019 {"sr.dz", OP_SI(0x8) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1020 {"sr.em", OP_REG(0x318) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1021 {"sr.em", OP_SI(0xC) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1022 {"sr.es", OP_REG(0x31A) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1023 {"sr.es", OP_SI(0xD) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1024 {"sr.ez", OP_REG(0x316) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1025 {"sr.ez", OP_SI(0xB) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1026 {"sr.im", OP_REG(0x31E) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1027 {"sr.im", OP_SI(0xF) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1028 {"sr.iz", OP_REG(0x31C) | i(0) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1029 {"sr.iz", OP_SI(0xE) | i(0) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1030
1031 /* Shift Register Right With Inverted Endmask */
1032
1033 {"sri.dm", OP_REG(0x312) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1034 {"sri.dm", OP_SI(0x9) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1035 {"sri.ds", OP_REG(0x314) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1036 {"sri.ds", OP_SI(0xA) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1037 {"sri.dz", OP_REG(0x310) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1038 {"sri.dz", OP_SI(0x8) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1039 {"sri.em", OP_REG(0x318) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1040 {"sri.em", OP_SI(0xC) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1041 {"sri.es", OP_REG(0x31A) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1042 {"sri.es", OP_SI(0xD) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1043 {"sri.ez", OP_REG(0x316) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1044 {"sri.ez", OP_SI(0xB) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1045 {"sri.im", OP_REG(0x31E) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1046 {"sri.im", OP_SI(0xF) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1047 {"sri.iz", OP_REG(0x31C) | i(1) | n(1), MASK_REG | i(1) | n(1), 0, {REG_0, ENDMASK, REG_22, REG_DEST} },
1048 {"sri.iz", OP_SI(0xE) | i(1) | n(1), MASK_SI | i(1) | n(1), 0, {ROTATE, ENDMASK, REG_22, REG_DEST} },
1049
1050 /* Store Data into Memory */
1051
1052 {"st", OP_SI(0x32), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST}},
1053 {"st", OP_LI(0x365) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
1054 {"st", OP_REG(0x364) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
1055 {"st.b", OP_SI(0x30), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST}},
1056 {"st.b", OP_LI(0x361) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
1057 {"st.b", OP_REG(0x360) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
1058 {"st.d", OP_SI(0x33), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST_E}},
1059 {"st.d", OP_LI(0x367) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST_E} },
1060 {"st.d", OP_REG(0x366) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST_E} },
1061 {"st.h", OP_SI(0x31), (MASK_SI & ~M_SI(1)), 0, {SSI, REG_BASE_M_SI, REG_DEST}},
1062 {"st.h", OP_LI(0x363) | D(0), (MASK_LI & ~M_REG(1)) | D(1), 0, {LSI_SCALED, REG_BASE_M_LI, REG_DEST} },
1063 {"st.h", OP_REG(0x362) | D(0), (MASK_REG & ~M_REG(1)) | D(1), 0, {REG_SCALED, REG_BASE_M_LI, REG_DEST} },
1064
1065 /* Signed Integer Subtract */
1066
1067 {"sub", OP_SI(0x5A), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
1068 {"sub", OP_LI(0x3B5), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
1069 {"sub", OP_REG(0x3B4), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1070
1071 /* Unsigned Integer Subtract */
1072
1073 {"subu", OP_SI(0x5B), MASK_SI, 0, {SSI, REG_22, REG_DEST} },
1074 {"subu", OP_LI(0x3B7), MASK_LI, 0, {LSI, REG_22, REG_DEST} },
1075 {"subu", OP_REG(0x3B6), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1076
1077 /* Write Control Register
1078 Is a special form of the "swcr" instruction so comes before it in the table. */
1079
1080 {"wrcr", OP_SI(0x5), MASK_SI | (0x1F << 27), 0, {CR_SI, REG_22} },
1081 {"wrcr", OP_LI(0x30B), MASK_LI | (0x1F << 27), 0, {CR_LI, REG_22} },
1082 {"wrcr", OP_REG(0x30A), MASK_REG | (0x1F << 27), 0, {REG_0, REG_22} },
1083
1084 /* Swap Control Register */
1085
1086 {"swcr", OP_SI(0x5), MASK_SI, 0, {CR_SI, REG_22, REG_DEST} },
1087 {"swcr", OP_LI(0x30B), MASK_LI, 0, {CR_LI, REG_22, REG_DEST} },
1088 {"swcr", OP_REG(0x30A), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1089
1090 /* Trap */
1091
1092 {"trap", OP_SI(0x1) | E(0), MASK_SI | E(1), 0, {SUI} },
1093 {"trap", OP_LI(0x303) | E(0), MASK_LI | E(1), 0, {LUI} },
1094 {"trap", OP_REG(0x302) | E(0), MASK_REG | E(1), 0, {REG_0} },
1095
1096 /* Vector Floating-Point Add */
1097
1098 {"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} },
1099 {"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} },
1100 {"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} },
1101 {"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} },
1102 {"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} },
1103
1104 /* Vector Floating-Point Multiply and Add to Accumulator FIXME! This is not yet fully implemented.
1105 From the documentation there appears to be no way to tell the difference between the opcodes for
1106 instructions that have register destinations and instructions that have accumulator destinations.
1107 Further investigation is necessary. Since this isn't critical to getting a TIC80 toolchain up
1108 and running, it is defered until later. */
1109
1110 /* Vector Floating-Point Multiply
1111 Note: If r0 is in the destination reg, then this is a "vector nop" instruction. */
1112
1113 {"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} },
1114 {"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} },
1115 {"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} },
1116 {"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} },
1117 {"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} },
1118
1119 /* Vector Floating-Point Multiply and Subtract from Accumulator
1120 FIXME: See note above for vmac instruction */
1121
1122 /* Vector Floating-Point Subtract Accumulator From Source
1123 FIXME: See note above for vmac instruction */
1124
1125 /* Vector Round With Floating-Point Input
1126 FIXME: See note above for vmac instruction */
1127
1128 /* Vector Round with Integer Input */
1129
1130 {"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}},
1131 {"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}},
1132 {"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}},
1133 {"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}},
1134 {"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}},
1135 {"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}},
1136 {"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}},
1137 {"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}},
1138
1139 /* Vector Floating-Point Subtract */
1140
1141 {"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} },
1142 {"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} },
1143 {"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} },
1144 {"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} },
1145 {"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} },
1146
1147 /* Vector Load Data Into Register - Note that the vector load/store instructions come after the other
1148 vector instructions so that the disassembler will always print the load/store instruction second for
1149 vector instructions that have two instructions in the same opcode. */
1150
1151 {"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} },
1152 {"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} },
1153 {"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} },
1154 {"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} },
1155
1156 /* Vector Store Data Into Memory - Note that the vector load/store instructions come after the other
1157 vector instructions so that the disassembler will always print the load/store instruction second for
1158 vector instructions that have two instructions in the same opcode. */
1159
1160 {"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} },
1161 {"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} },
1162
1163 {"xnor", OP_SI(0x19), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
1164 {"xnor", OP_LI(0x333), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
1165 {"xnor", OP_REG(0x332), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1166
1167 {"xor", OP_SI(0x16), MASK_SI, 0, {SUBF, REG_22, REG_DEST} },
1168 {"xor", OP_LI(0x32D), MASK_LI, 0, {LUBF, REG_22, REG_DEST} },
1169 {"xor", OP_REG(0x32C), MASK_REG, 0, {REG_0, REG_22, REG_DEST} },
1170
1171 };
1172
1173 const int tic80_num_opcodes = sizeof (tic80_opcodes) / sizeof (tic80_opcodes[0]);