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