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