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