1/* Instruction opcode table for ip2k. 2 3THIS FILE IS MACHINE GENERATED WITH CGEN. 4 5Copyright (C) 1996-2017 Free Software Foundation, Inc. 6 7This 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. */ 38unsigned int 39ip2k_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 55int 56ip2k_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 72static int asm_hash_insn_p (const CGEN_INSN *); 73static unsigned int asm_hash_insn (const char *); 74static int dis_hash_insn_p (const CGEN_INSN *); 75static 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] 80static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = { 81 0, 0, 0x0, { { 0 } } 82}; 83 84static const CGEN_IFMT ifmt_jmp ATTRIBUTE_UNUSED = { 85 16, 16, 0xe000, { { F (F_OP3) }, { F (F_ADDR16CJP) }, { 0 } } 86}; 87 88static const CGEN_IFMT ifmt_sb ATTRIBUTE_UNUSED = { 89 16, 16, 0xf000, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 90}; 91 92static const CGEN_IFMT ifmt_xorw_l ATTRIBUTE_UNUSED = { 93 16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } } 94}; 95 96static const CGEN_IFMT ifmt_loadl_a ATTRIBUTE_UNUSED = { 97 16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } } 98}; 99 100static const CGEN_IFMT ifmt_loadh_a ATTRIBUTE_UNUSED = { 101 16, 16, 0xff00, { { F (F_OP4) }, { F (F_OP4MID) }, { F (F_IMM8) }, { 0 } } 102}; 103 104static const CGEN_IFMT ifmt_addcfr_w ATTRIBUTE_UNUSED = { 105 16, 16, 0xfe00, { { F (F_OP6) }, { F (F_DIR) }, { F (F_REG) }, { 0 } } 106}; 107 108static const CGEN_IFMT ifmt_speed ATTRIBUTE_UNUSED = { 109 16, 16, 0xff00, { { F (F_OP8) }, { F (F_IMM8) }, { 0 } } 110}; 111 112static const CGEN_IFMT ifmt_ireadi ATTRIBUTE_UNUSED = { 113 16, 16, 0xffff, { { F (F_OP6) }, { F (F_OP6_10LOW) }, { 0 } } 114}; 115 116static const CGEN_IFMT ifmt_page ATTRIBUTE_UNUSED = { 117 16, 16, 0xfff8, { { F (F_OP6) }, { F (F_OP6_7LOW) }, { F (F_PAGE3) }, { 0 } } 118}; 119 120static 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 133static 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] 665static const CGEN_IFMT ifmt_sc ATTRIBUTE_UNUSED = { 666 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 667}; 668 669static const CGEN_IFMT ifmt_snc ATTRIBUTE_UNUSED = { 670 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 671}; 672 673static const CGEN_IFMT ifmt_sz ATTRIBUTE_UNUSED = { 674 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 675}; 676 677static const CGEN_IFMT ifmt_snz ATTRIBUTE_UNUSED = { 678 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 679}; 680 681static const CGEN_IFMT ifmt_skip ATTRIBUTE_UNUSED = { 682 16, 16, 0xffff, { { F (F_OP4) }, { F (F_BITNO) }, { F (F_REG) }, { 0 } } 683}; 684 685static 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 700static 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 736static 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 792static int 793asm_hash_insn_p (const CGEN_INSN *insn ATTRIBUTE_UNUSED) 794{ 795 return CGEN_ASM_HASH_P (insn); 796} 797 798static int 799dis_hash_insn_p (const CGEN_INSN *insn) 800{ 801 /* If building the hash table and the NO-DIS attribute is present, 802 ignore. */ 803 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NO_DIS)) 804 return 0; 805 return CGEN_DIS_HASH_P (insn); 806} 807 808#ifndef CGEN_ASM_HASH 809#define CGEN_ASM_HASH_SIZE 127 810#ifdef CGEN_MNEMONIC_OPERANDS 811#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) 812#else 813#define CGEN_ASM_HASH(mnem) (*(unsigned char *) (mnem) % CGEN_ASM_HASH_SIZE) /*FIXME*/ 814#endif 815#endif 816 817/* It doesn't make much sense to provide a default here, 818 but while this is under development we do. 819 BUFFER is a pointer to the bytes of the insn, target order. 820 VALUE is the first base_insn_bitsize bits as an int in host order. */ 821 822#ifndef CGEN_DIS_HASH 823#define CGEN_DIS_HASH_SIZE 256 824#define CGEN_DIS_HASH(buf, value) (*(unsigned char *) (buf)) 825#endif 826 827/* The result is the hash value of the insn. 828 Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */ 829 830static unsigned int 831asm_hash_insn (const char *mnem) 832{ 833 return CGEN_ASM_HASH (mnem); 834} 835 836/* BUF is a pointer to the bytes of the insn, target order. 837 VALUE is the first base_insn_bitsize bits as an int in host order. */ 838 839static unsigned int 840dis_hash_insn (const char *buf ATTRIBUTE_UNUSED, 841 CGEN_INSN_INT value ATTRIBUTE_UNUSED) 842{ 843 return CGEN_DIS_HASH (buf, value); 844} 845 846/* Set the recorded length of the insn in the CGEN_FIELDS struct. */ 847 848static void 849set_fields_bitsize (CGEN_FIELDS *fields, int size) 850{ 851 CGEN_FIELDS_BITSIZE (fields) = size; 852} 853 854/* Function to call before using the operand instance table. 855 This plugs the opcode entries and macro instructions into the cpu table. */ 856 857void 858ip2k_cgen_init_opcode_table (CGEN_CPU_DESC cd) 859{ 860 int i; 861 int num_macros = (sizeof (ip2k_cgen_macro_insn_table) / 862 sizeof (ip2k_cgen_macro_insn_table[0])); 863 const CGEN_IBASE *ib = & ip2k_cgen_macro_insn_table[0]; 864 const CGEN_OPCODE *oc = & ip2k_cgen_macro_insn_opcode_table[0]; 865 CGEN_INSN *insns = xmalloc (num_macros * sizeof (CGEN_INSN)); 866 867 /* This test has been added to avoid a warning generated 868 if memset is called with a third argument of value zero. */ 869 if (num_macros >= 1) 870 memset (insns, 0, num_macros * sizeof (CGEN_INSN)); 871 for (i = 0; i < num_macros; ++i) 872 { 873 insns[i].base = &ib[i]; 874 insns[i].opcode = &oc[i]; 875 ip2k_cgen_build_insn_regex (& insns[i]); 876 } 877 cd->macro_insn_table.init_entries = insns; 878 cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); 879 cd->macro_insn_table.num_init_entries = num_macros; 880 881 oc = & ip2k_cgen_insn_opcode_table[0]; 882 insns = (CGEN_INSN *) cd->insn_table.init_entries; 883 for (i = 0; i < MAX_INSNS; ++i) 884 { 885 insns[i].opcode = &oc[i]; 886 ip2k_cgen_build_insn_regex (& insns[i]); 887 } 888 889 cd->sizeof_fields = sizeof (CGEN_FIELDS); 890 cd->set_fields_bitsize = set_fields_bitsize; 891 892 cd->asm_hash_p = asm_hash_insn_p; 893 cd->asm_hash = asm_hash_insn; 894 cd->asm_hash_size = CGEN_ASM_HASH_SIZE; 895 896 cd->dis_hash_p = dis_hash_insn_p; 897 cd->dis_hash = dis_hash_insn; 898 cd->dis_hash_size = CGEN_DIS_HASH_SIZE; 899} 900