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