Implement frame apply [all | COUNT | -COUNT | level LEVEL... ] [FLAG]... COMMAND.
[external/binutils.git] / opcodes / tic80-opc.c
1 /* Opcode table for TI TMS320C80 (MVP).
2    Copyright (C) 1996-2018 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]);