1 /* Instruction opcode table for ip2k. 2 3 THIS FILE IS MACHINE GENERATED WITH CGEN. 4 5 Copyright (C) 1996-2014 Free Software Foundation, Inc. 6 7 This file is part of the GNU Binutils and/or GDB, the GNU debugger. 8 9 This file is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3, or (at your option) 12 any later version. 13 14 It is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 License for more details. 18 19 You should have received a copy of the GNU General Public License along 20 with this program; if not, write to the Free Software Foundation, Inc., 21 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 22 23 */ 24 25 #include "sysdep.h" 26 #include "ansidecl.h" 27 #include "bfd.h" 28 #include "symcat.h" 29 #include "ip2k-desc.h" 30 #include "ip2k-opc.h" 31 #include "libiberty.h" 32 33 /* -- opc.c */ 34 35 #include "safe-ctype.h" 36 37 /* A better hash function for instruction mnemonics. */ 38 unsigned int 39 ip2k_asm_hash (const char* insn) 40 { 41 unsigned int hash; 42 const char* m = insn; 43 44 for (hash = 0; *m && ! ISSPACE (*m); m++) 45 hash = (hash * 23) ^ (0x1F & TOLOWER (*m)); 46 47 /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */ 48 49 return hash % CGEN_ASM_HASH_SIZE; 50 } 51 52 53 /* Special check to ensure that instruction exists for given machine. */ 54 55 int 56 ip2k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) 57 { 58 int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); 59 60 /* No mach attribute? Assume it's supported for all machs. */ 61 if (machs == 0) 62 return 1; 63 64 return (machs & cd->machs) != 0; 65 } 66 67 68 /* -- asm.c */ 70 /* The hash functions are recorded here to help keep assembler code out of 71 the disassembler and vice versa. */ 72 73 static int asm_hash_insn_p (const CGEN_INSN *); 74 static unsigned int asm_hash_insn (const char *); 75 static int dis_hash_insn_p (const CGEN_INSN *); 76 static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT); 77 78 /* Instruction formats. */ 79 80 #define F(f) & ip2k_cgen_ifld_table[IP2K_##f] 81 static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = { 82 0, 0, 0x0, { { 0 } } 83 }; 84 85 static const CGEN_IFMT ifmt_jmp ATTRIBUTE_UNUSED = { 86 16, 16, 0xe000, { { F (F_OP3) }, { F (F_ADDR16CJP) }, { 0 } } 87 }; 88 89 static const CGEN_IFMT ifmt_sb ATTRIBUTE_UNUSED = { 90 16, 16, 0xf000, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 91 }; 92 93 static const CGEN_IFMT ifmt_xorw_l ATTRIBUTE_UNUSED = { 94 16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } } 95 }; 96 97 static const CGEN_IFMT ifmt_loadl_a ATTRIBUTE_UNUSED = { 98 16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } } 99 }; 100 101 static const CGEN_IFMT ifmt_loadh_a ATTRIBUTE_UNUSED = { 102 16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } } 103 }; 104 105 static const CGEN_IFMT ifmt_addcfr_w ATTRIBUTE_UNUSED = { 106 16, 16, 0xfe00, { { F (F_OP6) }, { F (F_DIR) }, { F (F_REG) }, { 0 } } 107 }; 108 109 static const CGEN_IFMT ifmt_speed ATTRIBUTE_UNUSED = { 110 16, 16, 0xff00, { { F (F_OP8) }, { F (F_IMM8) }, { 0 } } 111 }; 112 113 static const CGEN_IFMT ifmt_ireadi ATTRIBUTE_UNUSED = { 114 16, 16, 0xffff, { { F (F_OP6) }, { F (F_OP6_10LOW) }, { 0 } } 115 }; 116 117 static const CGEN_IFMT ifmt_page ATTRIBUTE_UNUSED = { 118 16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_PAGE3) }, { 0 } } 119 }; 120 121 static const CGEN_IFMT ifmt_reti ATTRIBUTE_UNUSED = { 122 16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_RETI3) }, { 0 } } 123 }; 124 125 #undef F 126 127 #define A(a) (1 << CGEN_INSN_##a) 128 #define OPERAND(op) IP2K_OPERAND_##op 129 #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ 130 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) 131 132 /* The instruction table. */ 133 134 static const CGEN_OPCODE ip2k_cgen_insn_opcode_table[MAX_INSNS] = 135 { 136 /* Special null first entry. 137 A `num' value of zero is thus invalid. 138 Also, the special `invalid' insn resides here. */ 139 { { 0, 0, 0, 0 }, {{0}}, 0, {0}}, 140 /* jmp $addr16cjp */ 141 { 142 { 0, 0, 0, 0 }, 143 { { MNEM, ' ', OP (ADDR16CJP), 0 } }, 144 & ifmt_jmp, { 0xe000 } 145 }, 146 /* call $addr16cjp */ 147 { 148 { 0, 0, 0, 0 }, 149 { { MNEM, ' ', OP (ADDR16CJP), 0 } }, 150 & ifmt_jmp, { 0xc000 } 151 }, 152 /* sb $fr,$bitno */ 153 { 154 { 0, 0, 0, 0 }, 155 { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } }, 156 & ifmt_sb, { 0xb000 } 157 }, 158 /* snb $fr,$bitno */ 159 { 160 { 0, 0, 0, 0 }, 161 { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } }, 162 & ifmt_sb, { 0xa000 } 163 }, 164 /* setb $fr,$bitno */ 165 { 166 { 0, 0, 0, 0 }, 167 { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } }, 168 & ifmt_sb, { 0x9000 } 169 }, 170 /* clrb $fr,$bitno */ 171 { 172 { 0, 0, 0, 0 }, 173 { { MNEM, ' ', OP (FR), ',', OP (BITNO), 0 } }, 174 & ifmt_sb, { 0x8000 } 175 }, 176 /* xor W,#$lit8 */ 177 { 178 { 0, 0, 0, 0 }, 179 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 180 & ifmt_xorw_l, { 0x7f00 } 181 }, 182 /* and W,#$lit8 */ 183 { 184 { 0, 0, 0, 0 }, 185 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 186 & ifmt_xorw_l, { 0x7e00 } 187 }, 188 /* or W,#$lit8 */ 189 { 190 { 0, 0, 0, 0 }, 191 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 192 & ifmt_xorw_l, { 0x7d00 } 193 }, 194 /* add W,#$lit8 */ 195 { 196 { 0, 0, 0, 0 }, 197 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 198 & ifmt_xorw_l, { 0x7b00 } 199 }, 200 /* sub W,#$lit8 */ 201 { 202 { 0, 0, 0, 0 }, 203 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 204 & ifmt_xorw_l, { 0x7a00 } 205 }, 206 /* cmp W,#$lit8 */ 207 { 208 { 0, 0, 0, 0 }, 209 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 210 & ifmt_xorw_l, { 0x7900 } 211 }, 212 /* retw #$lit8 */ 213 { 214 { 0, 0, 0, 0 }, 215 { { MNEM, ' ', '#', OP (LIT8), 0 } }, 216 & ifmt_xorw_l, { 0x7800 } 217 }, 218 /* cse W,#$lit8 */ 219 { 220 { 0, 0, 0, 0 }, 221 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 222 & ifmt_xorw_l, { 0x7700 } 223 }, 224 /* csne W,#$lit8 */ 225 { 226 { 0, 0, 0, 0 }, 227 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 228 & ifmt_xorw_l, { 0x7600 } 229 }, 230 /* push #$lit8 */ 231 { 232 { 0, 0, 0, 0 }, 233 { { MNEM, ' ', '#', OP (LIT8), 0 } }, 234 & ifmt_xorw_l, { 0x7400 } 235 }, 236 /* muls W,#$lit8 */ 237 { 238 { 0, 0, 0, 0 }, 239 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 240 & ifmt_xorw_l, { 0x7300 } 241 }, 242 /* mulu W,#$lit8 */ 243 { 244 { 0, 0, 0, 0 }, 245 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 246 & ifmt_xorw_l, { 0x7200 } 247 }, 248 /* loadl #$lit8 */ 249 { 250 { 0, 0, 0, 0 }, 251 { { MNEM, ' ', '#', OP (LIT8), 0 } }, 252 & ifmt_xorw_l, { 0x7100 } 253 }, 254 /* loadh #$lit8 */ 255 { 256 { 0, 0, 0, 0 }, 257 { { MNEM, ' ', '#', OP (LIT8), 0 } }, 258 & ifmt_xorw_l, { 0x7000 } 259 }, 260 /* loadl $addr16l */ 261 { 262 { 0, 0, 0, 0 }, 263 { { MNEM, ' ', OP (ADDR16L), 0 } }, 264 & ifmt_loadl_a, { 0x7100 } 265 }, 266 /* loadh $addr16h */ 267 { 268 { 0, 0, 0, 0 }, 269 { { MNEM, ' ', OP (ADDR16H), 0 } }, 270 & ifmt_loadh_a, { 0x7000 } 271 }, 272 /* addc $fr,W */ 273 { 274 { 0, 0, 0, 0 }, 275 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 276 & ifmt_addcfr_w, { 0x5e00 } 277 }, 278 /* addc W,$fr */ 279 { 280 { 0, 0, 0, 0 }, 281 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 282 & ifmt_addcfr_w, { 0x5c00 } 283 }, 284 /* incsnz $fr */ 285 { 286 { 0, 0, 0, 0 }, 287 { { MNEM, ' ', OP (FR), 0 } }, 288 & ifmt_addcfr_w, { 0x5a00 } 289 }, 290 /* incsnz W,$fr */ 291 { 292 { 0, 0, 0, 0 }, 293 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 294 & ifmt_addcfr_w, { 0x5800 } 295 }, 296 /* muls W,$fr */ 297 { 298 { 0, 0, 0, 0 }, 299 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 300 & ifmt_addcfr_w, { 0x5400 } 301 }, 302 /* mulu W,$fr */ 303 { 304 { 0, 0, 0, 0 }, 305 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 306 & ifmt_addcfr_w, { 0x5000 } 307 }, 308 /* decsnz $fr */ 309 { 310 { 0, 0, 0, 0 }, 311 { { MNEM, ' ', OP (FR), 0 } }, 312 & ifmt_addcfr_w, { 0x4e00 } 313 }, 314 /* decsnz W,$fr */ 315 { 316 { 0, 0, 0, 0 }, 317 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 318 & ifmt_addcfr_w, { 0x4c00 } 319 }, 320 /* subc W,$fr */ 321 { 322 { 0, 0, 0, 0 }, 323 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 324 & ifmt_addcfr_w, { 0x4800 } 325 }, 326 /* subc $fr,W */ 327 { 328 { 0, 0, 0, 0 }, 329 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 330 & ifmt_addcfr_w, { 0x4a00 } 331 }, 332 /* pop $fr */ 333 { 334 { 0, 0, 0, 0 }, 335 { { MNEM, ' ', OP (FR), 0 } }, 336 & ifmt_addcfr_w, { 0x4600 } 337 }, 338 /* push $fr */ 339 { 340 { 0, 0, 0, 0 }, 341 { { MNEM, ' ', OP (FR), 0 } }, 342 & ifmt_addcfr_w, { 0x4400 } 343 }, 344 /* cse W,$fr */ 345 { 346 { 0, 0, 0, 0 }, 347 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 348 & ifmt_addcfr_w, { 0x4200 } 349 }, 350 /* csne W,$fr */ 351 { 352 { 0, 0, 0, 0 }, 353 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 354 & ifmt_addcfr_w, { 0x4000 } 355 }, 356 /* incsz $fr */ 357 { 358 { 0, 0, 0, 0 }, 359 { { MNEM, ' ', OP (FR), 0 } }, 360 & ifmt_addcfr_w, { 0x3e00 } 361 }, 362 /* incsz W,$fr */ 363 { 364 { 0, 0, 0, 0 }, 365 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 366 & ifmt_addcfr_w, { 0x3c00 } 367 }, 368 /* swap $fr */ 369 { 370 { 0, 0, 0, 0 }, 371 { { MNEM, ' ', OP (FR), 0 } }, 372 & ifmt_addcfr_w, { 0x3a00 } 373 }, 374 /* swap W,$fr */ 375 { 376 { 0, 0, 0, 0 }, 377 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 378 & ifmt_addcfr_w, { 0x3800 } 379 }, 380 /* rl $fr */ 381 { 382 { 0, 0, 0, 0 }, 383 { { MNEM, ' ', OP (FR), 0 } }, 384 & ifmt_addcfr_w, { 0x3600 } 385 }, 386 /* rl W,$fr */ 387 { 388 { 0, 0, 0, 0 }, 389 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 390 & ifmt_addcfr_w, { 0x3400 } 391 }, 392 /* rr $fr */ 393 { 394 { 0, 0, 0, 0 }, 395 { { MNEM, ' ', OP (FR), 0 } }, 396 & ifmt_addcfr_w, { 0x3200 } 397 }, 398 /* rr W,$fr */ 399 { 400 { 0, 0, 0, 0 }, 401 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 402 & ifmt_addcfr_w, { 0x3000 } 403 }, 404 /* decsz $fr */ 405 { 406 { 0, 0, 0, 0 }, 407 { { MNEM, ' ', OP (FR), 0 } }, 408 & ifmt_addcfr_w, { 0x2e00 } 409 }, 410 /* decsz W,$fr */ 411 { 412 { 0, 0, 0, 0 }, 413 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 414 & ifmt_addcfr_w, { 0x2c00 } 415 }, 416 /* inc $fr */ 417 { 418 { 0, 0, 0, 0 }, 419 { { MNEM, ' ', OP (FR), 0 } }, 420 & ifmt_addcfr_w, { 0x2a00 } 421 }, 422 /* inc W,$fr */ 423 { 424 { 0, 0, 0, 0 }, 425 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 426 & ifmt_addcfr_w, { 0x2800 } 427 }, 428 /* not $fr */ 429 { 430 { 0, 0, 0, 0 }, 431 { { MNEM, ' ', OP (FR), 0 } }, 432 & ifmt_addcfr_w, { 0x2600 } 433 }, 434 /* not W,$fr */ 435 { 436 { 0, 0, 0, 0 }, 437 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 438 & ifmt_addcfr_w, { 0x2400 } 439 }, 440 /* test $fr */ 441 { 442 { 0, 0, 0, 0 }, 443 { { MNEM, ' ', OP (FR), 0 } }, 444 & ifmt_addcfr_w, { 0x2200 } 445 }, 446 /* mov W,#$lit8 */ 447 { 448 { 0, 0, 0, 0 }, 449 { { MNEM, ' ', 'W', ',', '#', OP (LIT8), 0 } }, 450 & ifmt_xorw_l, { 0x7c00 } 451 }, 452 /* mov $fr,W */ 453 { 454 { 0, 0, 0, 0 }, 455 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 456 & ifmt_addcfr_w, { 0x200 } 457 }, 458 /* mov W,$fr */ 459 { 460 { 0, 0, 0, 0 }, 461 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 462 & ifmt_addcfr_w, { 0x2000 } 463 }, 464 /* add $fr,W */ 465 { 466 { 0, 0, 0, 0 }, 467 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 468 & ifmt_addcfr_w, { 0x1e00 } 469 }, 470 /* add W,$fr */ 471 { 472 { 0, 0, 0, 0 }, 473 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 474 & ifmt_addcfr_w, { 0x1c00 } 475 }, 476 /* xor $fr,W */ 477 { 478 { 0, 0, 0, 0 }, 479 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 480 & ifmt_addcfr_w, { 0x1a00 } 481 }, 482 /* xor W,$fr */ 483 { 484 { 0, 0, 0, 0 }, 485 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 486 & ifmt_addcfr_w, { 0x1800 } 487 }, 488 /* and $fr,W */ 489 { 490 { 0, 0, 0, 0 }, 491 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 492 & ifmt_addcfr_w, { 0x1600 } 493 }, 494 /* and W,$fr */ 495 { 496 { 0, 0, 0, 0 }, 497 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 498 & ifmt_addcfr_w, { 0x1400 } 499 }, 500 /* or $fr,W */ 501 { 502 { 0, 0, 0, 0 }, 503 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 504 & ifmt_addcfr_w, { 0x1200 } 505 }, 506 /* or W,$fr */ 507 { 508 { 0, 0, 0, 0 }, 509 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 510 & ifmt_addcfr_w, { 0x1000 } 511 }, 512 /* dec $fr */ 513 { 514 { 0, 0, 0, 0 }, 515 { { MNEM, ' ', OP (FR), 0 } }, 516 & ifmt_addcfr_w, { 0xe00 } 517 }, 518 /* dec W,$fr */ 519 { 520 { 0, 0, 0, 0 }, 521 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 522 & ifmt_addcfr_w, { 0xc00 } 523 }, 524 /* sub $fr,W */ 525 { 526 { 0, 0, 0, 0 }, 527 { { MNEM, ' ', OP (FR), ',', 'W', 0 } }, 528 & ifmt_addcfr_w, { 0xa00 } 529 }, 530 /* sub W,$fr */ 531 { 532 { 0, 0, 0, 0 }, 533 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 534 & ifmt_addcfr_w, { 0x800 } 535 }, 536 /* clr $fr */ 537 { 538 { 0, 0, 0, 0 }, 539 { { MNEM, ' ', OP (FR), 0 } }, 540 & ifmt_addcfr_w, { 0x600 } 541 }, 542 /* cmp W,$fr */ 543 { 544 { 0, 0, 0, 0 }, 545 { { MNEM, ' ', 'W', ',', OP (FR), 0 } }, 546 & ifmt_addcfr_w, { 0x400 } 547 }, 548 /* speed #$lit8 */ 549 { 550 { 0, 0, 0, 0 }, 551 { { MNEM, ' ', '#', OP (LIT8), 0 } }, 552 & ifmt_speed, { 0x100 } 553 }, 554 /* ireadi */ 555 { 556 { 0, 0, 0, 0 }, 557 { { MNEM, 0 } }, 558 & ifmt_ireadi, { 0x1d } 559 }, 560 /* iwritei */ 561 { 562 { 0, 0, 0, 0 }, 563 { { MNEM, 0 } }, 564 & ifmt_ireadi, { 0x1c } 565 }, 566 /* fread */ 567 { 568 { 0, 0, 0, 0 }, 569 { { MNEM, 0 } }, 570 & ifmt_ireadi, { 0x1b } 571 }, 572 /* fwrite */ 573 { 574 { 0, 0, 0, 0 }, 575 { { MNEM, 0 } }, 576 & ifmt_ireadi, { 0x1a } 577 }, 578 /* iread */ 579 { 580 { 0, 0, 0, 0 }, 581 { { MNEM, 0 } }, 582 & ifmt_ireadi, { 0x19 } 583 }, 584 /* iwrite */ 585 { 586 { 0, 0, 0, 0 }, 587 { { MNEM, 0 } }, 588 & ifmt_ireadi, { 0x18 } 589 }, 590 /* page $addr16p */ 591 { 592 { 0, 0, 0, 0 }, 593 { { MNEM, ' ', OP (ADDR16P), 0 } }, 594 & ifmt_page, { 0x10 } 595 }, 596 /* system */ 597 { 598 { 0, 0, 0, 0 }, 599 { { MNEM, 0 } }, 600 & ifmt_ireadi, { 0xff } 601 }, 602 /* reti #$reti3 */ 603 { 604 { 0, 0, 0, 0 }, 605 { { MNEM, ' ', '#', OP (RETI3), 0 } }, 606 & ifmt_reti, { 0x8 } 607 }, 608 /* ret */ 609 { 610 { 0, 0, 0, 0 }, 611 { { MNEM, 0 } }, 612 & ifmt_ireadi, { 0x7 } 613 }, 614 /* int */ 615 { 616 { 0, 0, 0, 0 }, 617 { { MNEM, 0 } }, 618 & ifmt_ireadi, { 0x6 } 619 }, 620 /* breakx */ 621 { 622 { 0, 0, 0, 0 }, 623 { { MNEM, 0 } }, 624 & ifmt_ireadi, { 0x5 } 625 }, 626 /* cwdt */ 627 { 628 { 0, 0, 0, 0 }, 629 { { MNEM, 0 } }, 630 & ifmt_ireadi, { 0x4 } 631 }, 632 /* ferase */ 633 { 634 { 0, 0, 0, 0 }, 635 { { MNEM, 0 } }, 636 & ifmt_ireadi, { 0x3 } 637 }, 638 /* retnp */ 639 { 640 { 0, 0, 0, 0 }, 641 { { MNEM, 0 } }, 642 & ifmt_ireadi, { 0x2 } 643 }, 644 /* break */ 645 { 646 { 0, 0, 0, 0 }, 647 { { MNEM, 0 } }, 648 & ifmt_ireadi, { 0x1 } 649 }, 650 /* nop */ 651 { 652 { 0, 0, 0, 0 }, 653 { { MNEM, 0 } }, 654 & ifmt_ireadi, { 0x0 } 655 }, 656 }; 657 658 #undef A 659 #undef OPERAND 660 #undef MNEM 661 #undef OP 662 663 /* Formats for ALIAS macro-insns. */ 664 665 #define F(f) & ip2k_cgen_ifld_table[IP2K_##f] 666 static const CGEN_IFMT ifmt_sc ATTRIBUTE_UNUSED = { 667 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 668 }; 669 670 static const CGEN_IFMT ifmt_snc ATTRIBUTE_UNUSED = { 671 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 672 }; 673 674 static const CGEN_IFMT ifmt_sz ATTRIBUTE_UNUSED = { 675 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 676 }; 677 678 static const CGEN_IFMT ifmt_snz ATTRIBUTE_UNUSED = { 679 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 680 }; 681 682 static const CGEN_IFMT ifmt_skip ATTRIBUTE_UNUSED = { 683 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 684 }; 685 686 static const CGEN_IFMT ifmt_skipb ATTRIBUTE_UNUSED = { 687 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 688 }; 689 690 #undef F 691 692 /* Each non-simple macro entry points to an array of expansion possibilities. */ 693 694 #define A(a) (1 << CGEN_INSN_##a) 695 #define OPERAND(op) IP2K_OPERAND_##op 696 #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ 697 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) 698 699 /* The macro instruction table. */ 700 701 static const CGEN_IBASE ip2k_cgen_macro_insn_table[] = 702 { 703 /* sc */ 704 { 705 -1, "sc", "sc", 16, 706 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 707 }, 708 /* snc */ 709 { 710 -1, "snc", "snc", 16, 711 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 712 }, 713 /* sz */ 714 { 715 -1, "sz", "sz", 16, 716 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 717 }, 718 /* snz */ 719 { 720 -1, "snz", "snz", 16, 721 { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 722 }, 723 /* skip */ 724 { 725 -1, "skip", "skip", 16, 726 { 0|A(SKIPA)|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 727 }, 728 /* skip */ 729 { 730 -1, "skipb", "skip", 16, 731 { 0|A(SKIPA)|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } } 732 }, 733 }; 734 735 /* The macro instruction opcode table. */ 736 737 static const CGEN_OPCODE ip2k_cgen_macro_insn_opcode_table[] = 738 { 739 /* sc */ 740 { 741 { 0, 0, 0, 0 }, 742 { { MNEM, 0 } }, 743 & ifmt_sc, { 0xb00b } 744 }, 745 /* snc */ 746 { 747 { 0, 0, 0, 0 }, 748 { { MNEM, 0 } }, 749 & ifmt_snc, { 0xa00b } 750 }, 751 /* sz */ 752 { 753 { 0, 0, 0, 0 }, 754 { { MNEM, 0 } }, 755 & ifmt_sz, { 0xb40b } 756 }, 757 /* snz */ 758 { 759 { 0, 0, 0, 0 }, 760 { { MNEM, 0 } }, 761 & ifmt_snz, { 0xa40b } 762 }, 763 /* skip */ 764 { 765 { 0, 0, 0, 0 }, 766 { { MNEM, 0 } }, 767 & ifmt_skip, { 0xa009 } 768 }, 769 /* skip */ 770 { 771 { 0, 0, 0, 0 }, 772 { { MNEM, 0 } }, 773 & ifmt_skipb, { 0xb009 } 774 }, 775 }; 776 777 #undef A 778 #undef OPERAND 779 #undef MNEM 780 #undef OP 781 782 #ifndef CGEN_ASM_HASH_P 783 #define CGEN_ASM_HASH_P(insn) 1 784 #endif 785 786 #ifndef CGEN_DIS_HASH_P 787 #define CGEN_DIS_HASH_P(insn) 1 788 #endif 789 790 /* Return non-zero if INSN is to be added to the hash table. 791 Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */ 792 793 static int 794 asm_hash_insn_p (insn) 795 const CGEN_INSN *insn ATTRIBUTE_UNUSED; 796 { 797 return CGEN_ASM_HASH_P (insn); 798 } 799 800 static int 801 dis_hash_insn_p (insn) 802 const CGEN_INSN *insn; 803 { 804 /* If building the hash table and the NO-DIS attribute is present, 805 ignore. */ 806 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS)) 807 return 0; 808 return CGEN_DIS_HASH_P (insn); 809 } 810 811 #ifndef CGEN_ASM_HASH 812 #define CGEN_ASM_HASH_SIZE 127 813 #ifdef CGEN_MNEMONIC_OPERANDS 814 #define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) 815 #else 816 #define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/ 817 #endif 818 #endif 819 820 /* It doesn't make much sense to provide a default here, 821 but while this is under development we do. 822 BUFFER is a pointer to the bytes of the insn, target order. 823 VALUE is the first base_insn_bitsize bits as an int in host order. */ 824 825 #ifndef CGEN_DIS_HASH 826 #define CGEN_DIS_HASH_SIZE 256 827 #define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf)) 828 #endif 829 830 /* The result is the hash value of the insn. 831 Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */ 832 833 static unsigned int 834 asm_hash_insn (mnem) 835 const char * mnem; 836 { 837 return CGEN_ASM_HASH (mnem); 838 } 839 840 /* BUF is a pointer to the bytes of the insn, target order. 841 VALUE is the first base_insn_bitsize bits as an int in host order. */ 842 843 static unsigned int 844 dis_hash_insn (buf, value) 845 const char * buf ATTRIBUTE_UNUSED; 846 CGEN_INSN_INT value ATTRIBUTE_UNUSED; 847 { 848 return CGEN_DIS_HASH (buf, value); 849 } 850 851 /* Set the recorded length of the insn in the CGEN_FIELDS struct. */ 852 853 static void 854 set_fields_bitsize (CGEN_FIELDS *fields, int size) 855 { 856 CGEN_FIELDS_BITSIZE (fields) = size; 857 } 858 859 /* Function to call before using the operand instance table. 860 This plugs the opcode entries and macro instructions into the cpu table. */ 861 862 void 863 ip2k_cgen_init_opcode_table (CGEN_CPU_DESC cd) 864 { 865 int i; 866 int num_macros = (sizeof (ip2k_cgen_macro_insn_table) / 867 sizeof (ip2k_cgen_macro_insn_table[0])); 868 const CGEN_IBASE *ib = & ip2k_cgen_macro_insn_table[0]; 869 const CGEN_OPCODE *oc = & ip2k_cgen_macro_insn_opcode_table[0]; 870 CGEN_INSN *insns = xmalloc (num_macros * sizeof (CGEN_INSN)); 871 872 /* This test has been added to avoid a warning generated 873 if memset is called with a third argument of value zero. */ 874 if (num_macros >= 1) 875 memset (insns, 0, num_macros * sizeof (CGEN_INSN)); 876 for (i = 0; i < num_macros; ++i) 877 { 878 insns[i].base = &ib[i]; 879 insns[i].opcode = &oc[i]; 880 ip2k_cgen_build_insn_regex (& insns[i]); 881 } 882 cd->macro_insn_table.init_entries = insns; 883 cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); 884 cd->macro_insn_table.num_init_entries = num_macros; 885 886 oc = & ip2k_cgen_insn_opcode_table[0]; 887 insns = (CGEN_INSN *) cd->insn_table.init_entries; 888 for (i = 0; i < MAX_INSNS; ++i) 889 { 890 insns[i].opcode = &oc[i]; 891 ip2k_cgen_build_insn_regex (& insns[i]); 892 } 893 894 cd->sizeof_fields = sizeof (CGEN_FIELDS); 895 cd->set_fields_bitsize = set_fields_bitsize; 896 897 cd->asm_hash_p = asm_hash_insn_p; 898 cd->asm_hash = asm_hash_insn; 899 cd->asm_hash_size = CGEN_ASM_HASH_SIZE; 900 901 cd->dis_hash_p = dis_hash_insn_p; 902 cd->dis_hash = dis_hash_insn; 903 cd->dis_hash_size = CGEN_DIS_HASH_SIZE; 904 } 905