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