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 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 52const 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 216const 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 235int 236tic80_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 275const char * 276tic80_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 308const struct predefined_symbol * 309tic80_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 329/* The operands table. The fields are: 330 331 bits, shift, insertion function, extraction function, flags 332 */ 333 334const 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 499const int tic80_num_operands = sizeof (tic80_operands)/sizeof(*tic80_operands); 500 501 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 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 592const 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 1211const int tic80_num_opcodes = sizeof (tic80_opcodes) / sizeof (tic80_opcodes[0]); 1212