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