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