1 /* Simulator/Opcode generator for the Renesas 2 (formerly Hitachi) / SuperH Inc. Super-H architecture. 3 4 Written by Steve Chamberlain of Cygnus Support. 5 sac@cygnus.com 6 7 This file is part of SH sim. 8 9 10 THIS SOFTWARE IS NOT COPYRIGHTED 11 12 Cygnus offers the following for use in the public domain. Cygnus 13 makes no warranty with regard to the software or it's performance 14 and the user accepts the software "AS IS" with all faults. 15 16 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO 17 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 20 */ 21 22 /* This program generates the opcode table for the assembler and 23 the simulator code. 24 25 -t prints a pretty table for the assembler manual 26 -s generates the simulator code jump table 27 -d generates a define table 28 -x generates the simulator code switch statement 29 default used to generate the opcode tables 30 31 */ 32 33 #include <ctype.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <unistd.h> 38 #include "libiberty.h" 39 40 #define MAX_NR_STUFF 42 41 42 typedef struct 43 { 44 const char * const defs; 45 const char * const refs; 46 const char * const name; 47 const char * const code; 48 const char * const stuff[MAX_NR_STUFF]; 49 int index; 50 } op; 51 52 53 static op tab[] = 54 { 55 56 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....", 57 { 58 "R[n] += SEXT (i);", 59 "if (i == 0) {", 60 " UNDEF(n); /* see #ifdef PARANOID */", 61 " break;", 62 "}", 63 }, 64 }, 65 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100", 66 { 67 "R[n] += R[m];", 68 }, 69 }, 70 71 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110", 72 { 73 "ult = R[n] + T;", 74 "SET_SR_T (ult < R[n]);", 75 "R[n] = ult + R[m];", 76 "SET_SR_T (T || (R[n] < ult));", 77 }, 78 }, 79 80 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111", 81 { 82 "ult = R[n] + R[m];", 83 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);", 84 "R[n] = ult;", 85 }, 86 }, 87 88 { "0", "0", "and #<imm>,R0", "11001001i8*1....", 89 { 90 "R0 &= i;", 91 }, 92 }, 93 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001", 94 { 95 "R[n] &= R[m];", 96 }, 97 }, 98 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....", 99 { 100 "MA (1);", 101 "WBAT (GBR + R0, RBAT (GBR + R0) & i);", 102 }, 103 }, 104 105 { "", "", "bf <bdisp8>", "10001011i8p1....", 106 { 107 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 108 "if (!T) {", 109 " SET_NIP (PC + 4 + (SEXT (i) * 2));", 110 " cycles += 2;", 111 "}", 112 }, 113 }, 114 115 { "", "", "bf.s <bdisp8>", "10001111i8p1....", 116 { 117 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 118 "if (!T) {", 119 " SET_NIP (PC + 4 + (SEXT (i) * 2));", 120 " cycles += 2;", 121 " Delay_Slot (PC + 2);", 122 "}", 123 }, 124 }, 125 126 { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001", 127 { 128 "/* 32-bit logical bit-manipulation instructions. */", 129 "int word2 = RIAT (nip);", 130 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 131 "i >>= 4; /* BOGUS: Using only three bits of 'i'. */", 132 "/* MSB of 'i' must be zero. */", 133 "if (i > 7)", 134 " RAISE_EXCEPTION (SIGILL);", 135 "MA (1);", 136 "do_blog_insn (1 << i, (word2 & 0xfff) + R[n],", 137 " (word2 >> 12) & 0xf, memory, maskb);", 138 "SET_NIP (nip + 2); /* Consume 2 more bytes. */", 139 }, 140 }, 141 { "", "", "bra <bdisp12>", "1010i12.........", 142 { 143 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 144 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));", 145 "cycles += 2;", 146 "Delay_Slot (PC + 2);", 147 }, 148 }, 149 150 { "", "n", "braf <REG_N>", "0000nnnn00100011", 151 { 152 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 153 "SET_NIP (PC + 4 + R[n]);", 154 "cycles += 2;", 155 "Delay_Slot (PC + 2);", 156 }, 157 }, 158 159 { "", "", "bsr <bdisp12>", "1011i12.........", 160 { 161 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 162 "PR = PH2T (PC + 4);", 163 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));", 164 "cycles += 2;", 165 "Delay_Slot (PC + 2);", 166 }, 167 }, 168 169 { "", "n", "bsrf <REG_N>", "0000nnnn00000011", 170 { 171 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 172 "PR = PH2T (PC) + 4;", 173 "SET_NIP (PC + 4 + R[n]);", 174 "cycles += 2;", 175 "Delay_Slot (PC + 2);", 176 }, 177 }, 178 179 { "", "", "bt <bdisp8>", "10001001i8p1....", 180 { 181 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 182 "if (T) {", 183 " SET_NIP (PC + 4 + (SEXT (i) * 2));", 184 " cycles += 2;", 185 "}", 186 }, 187 }, 188 189 { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1", 190 { 191 "/* MSB of 'i' is true for load, false for store. */", 192 "if (i <= 7)", 193 " if (T)", 194 " R[m] |= (1 << i);", 195 " else", 196 " R[m] &= ~(1 << i);", 197 "else", 198 " SET_SR_T ((R[m] & (1 << (i - 8))) != 0);", 199 }, 200 }, 201 { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1", 202 { 203 "/* MSB of 'i' is true for set, false for clear. */", 204 "if (i <= 7)", 205 " R[m] &= ~(1 << i);", 206 "else", 207 " R[m] |= (1 << (i - 8));", 208 }, 209 }, 210 { "n", "n", "clips.b <REG_N>", "0100nnnn10010001", 211 { 212 "if (R[n] < -128 || R[n] > 127) {", 213 " L (n);", 214 " SET_SR_CS (1);", 215 " if (R[n] > 127)", 216 " R[n] = 127;", 217 " else if (R[n] < -128)", 218 " R[n] = -128;", 219 "}", 220 }, 221 }, 222 { "n", "n", "clips.w <REG_N>", "0100nnnn10010101", 223 { 224 "if (R[n] < -32768 || R[n] > 32767) {", 225 " L (n);", 226 " SET_SR_CS (1);", 227 " if (R[n] > 32767)", 228 " R[n] = 32767;", 229 " else if (R[n] < -32768)", 230 " R[n] = -32768;", 231 "}", 232 }, 233 }, 234 { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001", 235 { 236 "if (R[n] < -256 || R[n] > 255) {", 237 " L (n);", 238 " SET_SR_CS (1);", 239 " R[n] = 255;", 240 "}", 241 }, 242 }, 243 { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101", 244 { 245 "if (R[n] < -65536 || R[n] > 65535) {", 246 " L (n);", 247 " SET_SR_CS (1);", 248 " R[n] = 65535;", 249 "}", 250 }, 251 }, 252 { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100", 253 { 254 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 255 "if (R0 == 0)", 256 " R[n] = 0x7fffffff;", 257 "else if (R0 == -1 && R[n] == 0x80000000)", 258 " R[n] = 0x7fffffff;", 259 "else R[n] /= R0;", 260 "L (n);", 261 }, 262 }, 263 { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100", 264 { 265 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 266 "if (R0 == 0)", 267 " R[n] = 0xffffffff;", 268 "/* FIXME: The result may be implementation-defined if it is outside */", 269 "/* the range of signed int (i.e. if R[n] was negative and R0 == 1). */", 270 "else R[n] = R[n] / (unsigned int) R0;", 271 "L (n);", 272 }, 273 }, 274 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000", 275 { 276 "R[n] = (R[n] * R0) & 0xffffffff;", 277 "L (n);", 278 }, 279 }, 280 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101", 281 { 282 "int regn = (R[n] >> 2) & 0x1f;", 283 "int bankn = (R[n] >> 7) & 0x1ff;", 284 "if (regn > 19)", 285 " regn = 19; /* FIXME what should happen? */", 286 "R0 = saved_state.asregs.regstack[bankn].regs[regn];", 287 "L (0);", 288 }, 289 }, 290 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001", 291 { 292 "int regn = (R[n] >> 2) & 0x1f;", 293 "int bankn = (R[n] >> 7) & 0x1ff;", 294 "if (regn > 19)", 295 " regn = 19; /* FIXME what should happen? */", 296 "saved_state.asregs.regstack[bankn].regs[regn] = R0;", 297 }, 298 }, 299 { "", "", "resbank", "0000000001011011", 300 { 301 "int i;", 302 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 303 /* FIXME: cdef all */ 304 "if (BO) { /* Bank Overflow */", 305 /* FIXME: how do we know when to reset BO? */ 306 " for (i = 0; i <= 14; i++) {", 307 " R[i] = RLAT (R[15]);", 308 " MA (1);", 309 " R[15] += 4;", 310 " }", 311 " PR = RLAT (R[15]);", 312 " R[15] += 4;", 313 " MA (1);", 314 " GBR = RLAT (R[15]);", 315 " R[15] += 4;", 316 " MA (1);", 317 " MACH = RLAT (R[15]);", 318 " R[15] += 4;", 319 " MA (1);", 320 " MACL = RLAT (R[15]);", 321 " R[15] += 4;", 322 " MA (1);", 323 "}", 324 "else if (BANKN == 0) /* Bank Underflow */", 325 " RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */ 326 "else {", 327 " SET_BANKN (BANKN - 1);", 328 " for (i = 0; i <= 14; i++)", 329 " R[i] = saved_state.asregs.regstack[BANKN].regs[i];", 330 " MACH = saved_state.asregs.regstack[BANKN].regs[15];", 331 " PR = saved_state.asregs.regstack[BANKN].regs[17];", 332 " GBR = saved_state.asregs.regstack[BANKN].regs[18];", 333 " MACL = saved_state.asregs.regstack[BANKN].regs[19];", 334 "}", 335 }, 336 }, 337 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001", 338 { 339 "/* Push Rn...R0 (if n==15, push pr and R14...R0). */", 340 "do {", 341 " MA (1);", 342 " R[15] -= 4;", 343 " if (n == 15)", 344 " WLAT (R[15], PR);", 345 " else", 346 " WLAT (R[15], R[n]);", 347 "} while (n-- > 0);", 348 }, 349 }, 350 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101", 351 { 352 "/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */", 353 "int i = 0;\n", 354 "do {", 355 " MA (1);", 356 " if (i == 15)", 357 " PR = RLAT (R[15]);", 358 " else", 359 " R[i] = RLAT (R[15]);", 360 " R[15] += 4;", 361 "} while (i++ < n);", 362 }, 363 }, 364 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000", 365 { 366 "/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */ 367 "int i = 15;\n", 368 "do {", 369 " MA (1);", 370 " R[15] -= 4;", 371 " if (i == 15)", 372 " WLAT (R[15], PR);", 373 " else", 374 " WLAT (R[15], R[i]);", 375 "} while (i-- > n);", 376 }, 377 }, 378 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100", 379 { 380 "/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */ 381 "do {", 382 " MA (1);", 383 " if (n == 15)", 384 " PR = RLAT (R[15]);", 385 " else", 386 " R[n] = RLAT (R[15]);", 387 " R[15] += 4;", 388 "} while (n++ < 15);", 389 }, 390 }, 391 { "", "", "nott", "0000000001101000", 392 { 393 "SET_SR_T (T == 0);", 394 }, 395 }, 396 397 { "", "", "bt.s <bdisp8>", "10001101i8p1....", 398 { 399 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 400 "if (T) {", 401 " SET_NIP (PC + 4 + (SEXT (i) * 2));", 402 " cycles += 2;", 403 " Delay_Slot (PC + 2);", 404 "}", 405 }, 406 }, 407 408 { "", "", "clrmac", "0000000000101000", 409 { 410 "MACH = 0;", 411 "MACL = 0;", 412 }, 413 }, 414 415 { "", "", "clrs", "0000000001001000", 416 { 417 "SET_SR_S (0);", 418 }, 419 }, 420 421 { "", "", "clrt", "0000000000001000", 422 { 423 "SET_SR_T (0);", 424 }, 425 }, 426 427 /* sh4a */ 428 { "", "", "clrdmxy", "0000000010001000", 429 { 430 "saved_state.asregs.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);" 431 }, 432 }, 433 434 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....", 435 { 436 "SET_SR_T (R0 == SEXT (i));", 437 }, 438 }, 439 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000", 440 { 441 "SET_SR_T (R[n] == R[m]);", 442 }, 443 }, 444 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011", 445 { 446 "SET_SR_T (R[n] >= R[m]);", 447 }, 448 }, 449 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111", 450 { 451 "SET_SR_T (R[n] > R[m]);", 452 }, 453 }, 454 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110", 455 { 456 "SET_SR_T (UR[n] > UR[m]);", 457 }, 458 }, 459 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010", 460 { 461 "SET_SR_T (UR[n] >= UR[m]);", 462 }, 463 }, 464 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101", 465 { 466 "SET_SR_T (R[n] > 0);", 467 }, 468 }, 469 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001", 470 { 471 "SET_SR_T (R[n] >= 0);", 472 }, 473 }, 474 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100", 475 { 476 "ult = R[n] ^ R[m];", 477 "SET_SR_T (((ult & 0xff000000) == 0)", 478 " | ((ult & 0xff0000) == 0)", 479 " | ((ult & 0xff00) == 0)", 480 " | ((ult & 0xff) == 0));", 481 }, 482 }, 483 484 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111", 485 { 486 "SET_SR_Q ((R[n] & sbit) != 0);", 487 "SET_SR_M ((R[m] & sbit) != 0);", 488 "SET_SR_T (M != Q);", 489 }, 490 }, 491 492 { "", "", "div0u", "0000000000011001", 493 { 494 "SET_SR_M (0);", 495 "SET_SR_Q (0);", 496 "SET_SR_T (0);", 497 }, 498 }, 499 500 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", 501 { 502 "div1 (&R0, m, n/*, T*/);", 503 }, 504 }, 505 506 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101", 507 { 508 "dmul_s (R[n], R[m]);", 509 }, 510 }, 511 512 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101", 513 { 514 "dmul_u (R[n], R[m]);", 515 }, 516 }, 517 518 { "n", "n", "dt <REG_N>", "0100nnnn00010000", 519 { 520 "R[n]--;", 521 "SET_SR_T (R[n] == 0);", 522 }, 523 }, 524 525 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110", 526 { 527 "R[n] = SEXT (R[m]);", 528 }, 529 }, 530 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111", 531 { 532 "R[n] = SEXTW (R[m]);", 533 }, 534 }, 535 536 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100", 537 { 538 "R[n] = (R[m] & 0xff);", 539 }, 540 }, 541 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101", 542 { 543 "R[n] = (R[m] & 0xffff);", 544 }, 545 }, 546 547 /* sh2e */ 548 { "", "", "fabs <FREG_N>", "1111nnnn01011101", 549 { 550 " union", 551 " {", 552 " unsigned int i;", 553 " float f;", 554 " } u;", 555 " u.f = FR (n);", 556 " u.i &= 0x7fffffff;", 557 " SET_FR (n, u.f);", 558 }, 559 }, 560 561 /* sh2e */ 562 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000", 563 { 564 "FP_OP (n, +, m);", 565 }, 566 }, 567 568 /* sh2e */ 569 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100", 570 { 571 "FP_CMP (n, ==, m);", 572 }, 573 }, 574 /* sh2e */ 575 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101", 576 { 577 "FP_CMP (n, >, m);", 578 }, 579 }, 580 581 /* sh4 */ 582 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101", 583 { 584 "if (! FPSCR_PR || n & 1)", 585 " RAISE_EXCEPTION (SIGILL);", 586 "else", 587 "{", 588 " union", 589 " {", 590 " int i;", 591 " float f;", 592 " } u;", 593 " u.f = DR (n);", 594 " FPUL = u.i;", 595 "}", 596 }, 597 }, 598 599 /* sh4 */ 600 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101", 601 { 602 "if (! FPSCR_PR || n & 1)", 603 " RAISE_EXCEPTION (SIGILL);", 604 "else", 605 "{", 606 " union", 607 " {", 608 " int i;", 609 " float f;", 610 " } u;", 611 " u.i = FPUL;", 612 " SET_DR (n, u.f);", 613 "}", 614 }, 615 }, 616 617 /* sh2e */ 618 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011", 619 { 620 "FP_OP (n, /, m);", 621 "/* FIXME: check for DP and (n & 1) == 0? */", 622 }, 623 }, 624 625 /* sh4 */ 626 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101", 627 { 628 "if (FPSCR_PR)", 629 " RAISE_EXCEPTION (SIGILL);", 630 "else", 631 "{", 632 " double fsum = 0;", 633 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)", 634 " RAISE_EXCEPTION (SIGILL);", 635 " /* FIXME: check for nans and infinities. */", 636 " fsum += FR (v1+0) * FR (v2+0);", 637 " fsum += FR (v1+1) * FR (v2+1);", 638 " fsum += FR (v1+2) * FR (v2+2);", 639 " fsum += FR (v1+3) * FR (v2+3);", 640 " SET_FR (v1+3, fsum);", 641 "}", 642 }, 643 }, 644 645 /* sh2e */ 646 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101", 647 { 648 "SET_FR (n, (float) 0.0);", 649 "/* FIXME: check for DP and (n & 1) == 0? */", 650 }, 651 }, 652 653 /* sh2e */ 654 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101", 655 { 656 "SET_FR (n, (float) 1.0);", 657 "/* FIXME: check for DP and (n & 1) == 0? */", 658 }, 659 }, 660 661 /* sh2e */ 662 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101", 663 { 664 " union", 665 " {", 666 " int i;", 667 " float f;", 668 " } u;", 669 " u.f = FR (n);", 670 " FPUL = u.i;", 671 }, 672 }, 673 674 /* sh2e */ 675 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101", 676 { 677 /* sh4 */ 678 "if (FPSCR_PR)", 679 " SET_DR (n, (double) FPUL);", 680 "else", 681 "{", 682 " SET_FR (n, (float) FPUL);", 683 "}", 684 }, 685 }, 686 687 /* sh2e */ 688 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110", 689 { 690 "SET_FR (n, FR (m) * FR (0) + FR (n));", 691 "/* FIXME: check for DP and (n & 1) == 0? */", 692 }, 693 }, 694 695 /* sh2e */ 696 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100", 697 { 698 /* sh4 */ 699 "if (FPSCR_SZ) {", 700 " int ni = XD_TO_XF (n);", 701 " int mi = XD_TO_XF (m);", 702 " SET_XF (ni + 0, XF (mi + 0));", 703 " SET_XF (ni + 1, XF (mi + 1));", 704 "}", 705 "else", 706 "{", 707 " SET_FR (n, FR (m));", 708 "}", 709 }, 710 }, 711 /* sh2e */ 712 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010", 713 { 714 /* sh4 */ 715 "if (FPSCR_SZ) {", 716 " MA (2);", 717 " WDAT (R[n], m);", 718 "}", 719 "else", 720 "{", 721 " MA (1);", 722 " WLAT (R[n], FI (m));", 723 "}", 724 }, 725 }, 726 /* sh2e */ 727 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000", 728 { 729 /* sh4 */ 730 "if (FPSCR_SZ) {", 731 " MA (2);", 732 " RDAT (R[m], n);", 733 "}", 734 "else", 735 "{", 736 " MA (1);", 737 " SET_FI (n, RLAT (R[m]));", 738 "}", 739 }, 740 }, 741 /* sh2a */ 742 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001", 743 { 744 "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)", 745 " and mov.bwl <REG_N>, @(disp12,<REG_M>)", 746 " and mov.bwl @(disp12,<REG_N>),<REG_M>", 747 " and movu.bw @(disp12,<REG_N>),<REG_M>. */", 748 "int word2 = RIAT (nip);", 749 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 750 "SET_NIP (nip + 2); /* Consume 2 more bytes. */", 751 "MA (1);", 752 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);", 753 }, 754 }, 755 /* sh2e */ 756 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001", 757 { 758 /* sh4 */ 759 "if (FPSCR_SZ) {", 760 " MA (2);", 761 " RDAT (R[m], n);", 762 " R[m] += 8;", 763 "}", 764 "else", 765 "{", 766 " MA (1);", 767 " SET_FI (n, RLAT (R[m]));", 768 " R[m] += 4;", 769 "}", 770 }, 771 }, 772 /* sh2e */ 773 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011", 774 { 775 /* sh4 */ 776 "if (FPSCR_SZ) {", 777 " MA (2);", 778 " R[n] -= 8;", 779 " WDAT (R[n], m);", 780 "}", 781 "else", 782 "{", 783 " MA (1);", 784 " R[n] -= 4;", 785 " WLAT (R[n], FI (m));", 786 "}", 787 }, 788 }, 789 /* sh2e */ 790 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110", 791 { 792 /* sh4 */ 793 "if (FPSCR_SZ) {", 794 " MA (2);", 795 " RDAT (R[0]+R[m], n);", 796 "}", 797 "else", 798 "{", 799 " MA (1);", 800 " SET_FI (n, RLAT (R[0] + R[m]));", 801 "}", 802 }, 803 }, 804 /* sh2e */ 805 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111", 806 { 807 /* sh4 */ 808 "if (FPSCR_SZ) {", 809 " MA (2);", 810 " WDAT (R[0]+R[n], m);", 811 "}", 812 "else", 813 "{", 814 " MA (1);", 815 " WLAT ((R[0]+R[n]), FI (m));", 816 "}", 817 }, 818 }, 819 820 /* sh4: 821 See fmov instructions above for move to/from extended fp registers. */ 822 823 /* sh2e */ 824 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010", 825 { 826 "FP_OP (n, *, m);", 827 }, 828 }, 829 830 /* sh2e */ 831 { "", "", "fneg <FREG_N>", "1111nnnn01001101", 832 { 833 " union", 834 " {", 835 " unsigned int i;", 836 " float f;", 837 " } u;", 838 " u.f = FR (n);", 839 " u.i ^= 0x80000000;", 840 " SET_FR (n, u.f);", 841 }, 842 }, 843 844 /* sh4a */ 845 { "", "", "fpchg", "1111011111111101", 846 { 847 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);", 848 }, 849 }, 850 851 /* sh4 */ 852 { "", "", "frchg", "1111101111111101", 853 { 854 "if (FPSCR_PR)", 855 " RAISE_EXCEPTION (SIGILL);", 856 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)", 857 " RAISE_EXCEPTION (SIGILL);", 858 "else", 859 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);", 860 }, 861 }, 862 863 /* sh4 */ 864 { "", "", "fsca", "1111eeee11111101", 865 { 866 "if (FPSCR_PR)", 867 " RAISE_EXCEPTION (SIGILL);", 868 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)", 869 " RAISE_EXCEPTION (SIGILL);", 870 "else", 871 " {", 872 " SET_FR (n, fsca_s (FPUL, &sin));", 873 " SET_FR (n+1, fsca_s (FPUL, &cos));", 874 " }", 875 }, 876 }, 877 878 /* sh4 */ 879 { "", "", "fschg", "1111001111111101", 880 { 881 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);", 882 }, 883 }, 884 885 /* sh3e */ 886 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101", 887 { 888 "FP_UNARY (n, sqrt);", 889 }, 890 }, 891 892 /* sh4 */ 893 { "", "", "fsrra <FREG_N>", "1111nnnn01111101", 894 { 895 "if (FPSCR_PR)", 896 " RAISE_EXCEPTION (SIGILL);", 897 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)", 898 " RAISE_EXCEPTION (SIGILL);", 899 "else", 900 " SET_FR (n, fsrra_s (FR (n)));", 901 }, 902 }, 903 904 /* sh2e */ 905 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001", 906 { 907 "FP_OP (n, -, m);", 908 }, 909 }, 910 911 /* sh2e */ 912 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101", 913 { 914 /* sh4 */ 915 "if (FPSCR_PR) {", 916 " if (DR (n) != DR (n)) /* NaN */", 917 " FPUL = 0x80000000;", 918 " else", 919 " FPUL = (int) DR (n);", 920 "}", 921 "else", 922 "if (FR (n) != FR (n)) /* NaN */", 923 " FPUL = 0x80000000;", 924 "else", 925 " FPUL = (int) FR (n);", 926 }, 927 }, 928 929 /* sh4 */ 930 { "", "", "ftrv <FV_N>", "1111vv0111111101", 931 { 932 "if (FPSCR_PR)", 933 " RAISE_EXCEPTION (SIGILL);", 934 "else", 935 "{", 936 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)", 937 " RAISE_EXCEPTION (SIGILL);", 938 " /* FIXME not implemented. */", 939 " printf (\"ftrv xmtrx, FV%d\\n\", v1);", 940 "}", 941 }, 942 }, 943 944 /* sh2e */ 945 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101", 946 { 947 " union", 948 " {", 949 " int i;", 950 " float f;", 951 " } u;", 952 " u.i = FPUL;", 953 " SET_FR (n, u.f);", 954 }, 955 }, 956 957 { "", "n", "jmp @<REG_N>", "0100nnnn00101011", 958 { 959 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 960 "SET_NIP (PT2H (R[n]));", 961 "cycles += 2;", 962 "Delay_Slot (PC + 2);", 963 }, 964 }, 965 966 { "", "n", "jsr @<REG_N>", "0100nnnn00001011", 967 { 968 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 969 "PR = PH2T (PC + 4);", 970 "if (~doprofile)", 971 " gotcall (PR, R[n]);", 972 "SET_NIP (PT2H (R[n]));", 973 "cycles += 2;", 974 "Delay_Slot (PC + 2);", 975 }, 976 }, 977 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011", 978 { 979 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 980 "PR = PH2T (PC + 2);", 981 "if (~doprofile)", 982 " gotcall (PR, R[n]);", 983 "SET_NIP (PT2H (R[n]));", 984 }, 985 }, 986 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....", 987 { 988 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 989 "PR = PH2T (PC + 2);", 990 "if (~doprofile)", 991 " gotcall (PR, i + TBR);", 992 "SET_NIP (PT2H (i + TBR));", 993 }, 994 }, 995 996 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110", 997 { 998 "CREG (m) = R[n];", 999 "/* FIXME: user mode */", 1000 }, 1001 }, 1002 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110", 1003 { 1004 "SET_SR (R[n]);", 1005 "/* FIXME: user mode */", 1006 }, 1007 }, 1008 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110", 1009 { 1010 "SET_MOD (R[n]);", 1011 }, 1012 }, 1013 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010", 1014 { 1015 "if (SR_MD)", 1016 " DBR = R[n]; /* priv mode */", 1017 "else", 1018 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1019 }, 1020 }, 1021 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010", 1022 { 1023 "if (SR_MD)", 1024 " SGR = R[n]; /* priv mode */", 1025 "else", 1026 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1027 }, 1028 }, 1029 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010", 1030 { 1031 "if (SR_MD)", /* FIXME? */ 1032 " TBR = R[n]; /* priv mode */", 1033 "else", 1034 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1035 }, 1036 }, 1037 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111", 1038 { 1039 "MA (1);", 1040 "CREG (m) = RLAT (R[n]);", 1041 "R[n] += 4;", 1042 "/* FIXME: user mode */", 1043 }, 1044 }, 1045 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111", 1046 { 1047 "MA (1);", 1048 "SET_SR (RLAT (R[n]));", 1049 "R[n] += 4;", 1050 "/* FIXME: user mode */", 1051 }, 1052 }, 1053 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111", 1054 { 1055 "MA (1);", 1056 "SET_MOD (RLAT (R[n]));", 1057 "R[n] += 4;", 1058 }, 1059 }, 1060 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110", 1061 { 1062 "if (SR_MD)", 1063 "{ /* priv mode */", 1064 " MA (1);", 1065 " DBR = RLAT (R[n]);", 1066 " R[n] += 4;", 1067 "}", 1068 "else", 1069 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1070 }, 1071 }, 1072 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110", 1073 { 1074 "if (SR_MD)", 1075 "{ /* priv mode */", 1076 " MA (1);", 1077 " SGR = RLAT (R[n]);", 1078 " R[n] += 4;", 1079 "}", 1080 "else", 1081 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1082 }, 1083 }, 1084 1085 /* sh-dsp */ 1086 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....", 1087 { 1088 "RE = SEXT (i) * 2 + 4 + PH2T (PC);", 1089 }, 1090 }, 1091 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....", 1092 { 1093 "RS = SEXT (i) * 2 + 4 + PH2T (PC);", 1094 }, 1095 }, 1096 1097 /* sh4a */ 1098 { "", "n", "ldrc <REG_N>", "0100nnnn00110100", 1099 { 1100 "SET_RC (R[n]);", 1101 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);", 1102 "CHECK_INSN_PTR (insn_ptr);", 1103 "RE |= 1;", 1104 }, 1105 }, 1106 { "", "", "ldrc #<imm>", "10001010i8*1....", 1107 { 1108 "SET_RC (i);", 1109 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);", 1110 "CHECK_INSN_PTR (insn_ptr);", 1111 "RE |= 1;", 1112 }, 1113 }, 1114 1115 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010", 1116 { 1117 "SREG (m) = R[n];", 1118 }, 1119 }, 1120 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110", 1121 { 1122 "MA (1);", 1123 "SREG (m) = RLAT (R[n]);", 1124 "R[n] += 4;", 1125 }, 1126 }, 1127 /* sh2e / sh-dsp (lds <REG_N>,DSR) */ 1128 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010", 1129 { 1130 "SET_FPSCR (R[n]);", 1131 }, 1132 }, 1133 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */ 1134 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110", 1135 { 1136 "MA (1);", 1137 "SET_FPSCR (RLAT (R[n]));", 1138 "R[n] += 4;", 1139 }, 1140 }, 1141 1142 { "", "", "ldtlb", "0000000000111000", 1143 { 1144 "/* We don't implement cache or tlb, so this is a noop. */", 1145 }, 1146 }, 1147 1148 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111", 1149 { 1150 "macl (&R0, memory, n, m);", 1151 }, 1152 }, 1153 1154 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111", 1155 { 1156 "macw (&R0, memory, n, m, endianw);", 1157 }, 1158 }, 1159 1160 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....", 1161 { 1162 "R[n] = SEXT (i);", 1163 }, 1164 }, 1165 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000", 1166 { 1167 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1168 "R[n] = ((i << 24) >> 12) | RIAT (nip);", 1169 "SET_NIP (nip + 2); /* Consume 2 more bytes. */", 1170 }, 1171 }, 1172 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001", 1173 { 1174 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1175 "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;", 1176 "SET_NIP (nip + 2); /* Consume 2 more bytes. */", 1177 }, 1178 }, 1179 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011", 1180 { 1181 "R[n] = R[m];", 1182 }, 1183 }, 1184 1185 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....", 1186 { 1187 "MA (1);", 1188 "R0 = RSBAT (i + GBR);", 1189 "L (0);", 1190 }, 1191 }, 1192 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1", 1193 { 1194 "MA (1);", 1195 "R0 = RSBAT (i + R[m]);", 1196 "L (0);", 1197 }, 1198 }, 1199 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100", 1200 { 1201 "MA (1);", 1202 "R[n] = RSBAT (R0 + R[m]);", 1203 "L (n);", 1204 }, 1205 }, 1206 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100", 1207 { 1208 "MA (1);", 1209 "R[n] = RSBAT (R[m]);", 1210 "R[m] += 1;", 1211 "L (n);", 1212 }, 1213 }, 1214 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011", 1215 { 1216 "MA (1);", 1217 "R[n] -= 1;", 1218 "R0 = RSBAT (R[n]);", 1219 "L (0);", 1220 }, 1221 }, 1222 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000", 1223 { 1224 "MA (1);", 1225 "WBAT (R[n], R[m]);", 1226 }, 1227 }, 1228 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....", 1229 { 1230 "MA (1);", 1231 "WBAT (i + GBR, R0);", 1232 }, 1233 }, 1234 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1", 1235 { 1236 "MA (1);", 1237 "WBAT (i + R[m], R0);", 1238 }, 1239 }, 1240 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100", 1241 { 1242 "MA (1);", 1243 "WBAT (R[n] + R0, R[m]);", 1244 }, 1245 }, 1246 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100", 1247 { 1248 /* Allow for the case where m == n. */ 1249 "int t = R[m];", 1250 "MA (1);", 1251 "R[n] -= 1;", 1252 "WBAT (R[n], t);", 1253 }, 1254 }, 1255 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011", 1256 { 1257 "MA (1);", 1258 "WBAT (R[n], R0);", 1259 "R[n] += 1;", 1260 }, 1261 }, 1262 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000", 1263 { 1264 "MA (1);", 1265 "R[n] = RSBAT (R[m]);", 1266 "L (n);", 1267 }, 1268 }, 1269 1270 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....", 1271 { 1272 "MA (1);", 1273 "R0 = RLAT (i + GBR);", 1274 "L (0);", 1275 }, 1276 }, 1277 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....", 1278 { 1279 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1280 "MA (1);", 1281 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);", 1282 "L (n);", 1283 }, 1284 }, 1285 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4", 1286 { 1287 "MA (1);", 1288 "R[n] = RLAT (i + R[m]);", 1289 "L (n);", 1290 }, 1291 }, 1292 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110", 1293 { 1294 "MA (1);", 1295 "R[n] = RLAT (R0 + R[m]);", 1296 "L (n);", 1297 }, 1298 }, 1299 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110", 1300 { 1301 "MA (1);", 1302 "R[n] = RLAT (R[m]);", 1303 "R[m] += 4;", 1304 "L (n);", 1305 }, 1306 }, 1307 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011", 1308 { 1309 "MA (1);", 1310 "R[n] -= 4;", 1311 "R0 = RLAT (R[n]);", 1312 "L (0);", 1313 }, 1314 }, 1315 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010", 1316 { 1317 "MA (1);", 1318 "R[n] = RLAT (R[m]);", 1319 "L (n);", 1320 }, 1321 }, 1322 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....", 1323 { 1324 "MA (1);", 1325 "WLAT (i + GBR, R0);", 1326 }, 1327 }, 1328 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4", 1329 { 1330 "MA (1);", 1331 "WLAT (i + R[n], R[m]);", 1332 }, 1333 }, 1334 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110", 1335 { 1336 "MA (1);", 1337 "WLAT (R0 + R[n], R[m]);", 1338 }, 1339 }, 1340 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110", 1341 { 1342 /* Allow for the case where m == n. */ 1343 "int t = R[m];", 1344 "MA (1) ;", 1345 "R[n] -= 4;", 1346 "WLAT (R[n], t);", 1347 }, 1348 }, 1349 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011", 1350 { 1351 "MA (1) ;", 1352 "WLAT (R[n], R0);", 1353 "R[n] += 4;", 1354 }, 1355 }, 1356 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010", 1357 { 1358 "MA (1);", 1359 "WLAT (R[n], R[m]);", 1360 }, 1361 }, 1362 1363 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....", 1364 { 1365 "MA (1);", 1366 "R0 = RSWAT (i + GBR);", 1367 "L (0);", 1368 }, 1369 }, 1370 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....", 1371 { 1372 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1373 "MA (1);", 1374 "R[n] = RSWAT (PH2T (PC + 4 + i));", 1375 "L (n);", 1376 }, 1377 }, 1378 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2", 1379 { 1380 "MA (1);", 1381 "R0 = RSWAT (i + R[m]);", 1382 "L (0);", 1383 }, 1384 }, 1385 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101", 1386 { 1387 "MA (1);", 1388 "R[n] = RSWAT (R0 + R[m]);", 1389 "L (n);", 1390 }, 1391 }, 1392 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101", 1393 { 1394 "MA (1);", 1395 "R[n] = RSWAT (R[m]);", 1396 "R[m] += 2;", 1397 "L (n);", 1398 }, 1399 }, 1400 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011", 1401 { 1402 "MA (1);", 1403 "R[n] -= 2;", 1404 "R0 = RSWAT (R[n]);", 1405 "L (0);", 1406 }, 1407 }, 1408 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001", 1409 { 1410 "MA (1);", 1411 "R[n] = RSWAT (R[m]);", 1412 "L (n);", 1413 }, 1414 }, 1415 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....", 1416 { 1417 "MA (1);", 1418 "WWAT (i + GBR, R0);", 1419 }, 1420 }, 1421 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2", 1422 { 1423 "MA (1);", 1424 "WWAT (i + R[m], R0);", 1425 }, 1426 }, 1427 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101", 1428 { 1429 "MA (1);", 1430 "WWAT (R0 + R[n], R[m]);", 1431 }, 1432 }, 1433 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101", 1434 { 1435 /* Allow for the case where m == n. */ 1436 "int t = R[m];", 1437 "MA (1);", 1438 "R[n] -= 2;", 1439 "WWAT (R[n], t);", 1440 }, 1441 }, 1442 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011", 1443 { 1444 "MA (1);", 1445 "WWAT (R[n], R0);", 1446 "R[n] += 2;", 1447 }, 1448 }, 1449 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001", 1450 { 1451 "MA (1);", 1452 "WWAT (R[n], R[m]);", 1453 }, 1454 }, 1455 1456 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....", 1457 { 1458 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1459 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);", 1460 }, 1461 }, 1462 1463 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011", 1464 { 1465 "/* We don't simulate cache, so this insn is identical to mov. */", 1466 "MA (1);", 1467 "WLAT (R[n], R[0]);", 1468 }, 1469 }, 1470 1471 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011", 1472 { 1473 "/* LDST -> T */", 1474 "SET_SR_T (LDST);", 1475 "/* if (T) R0 -> (Rn) */", 1476 "if (T)", 1477 " WLAT (R[n], R[0]);", 1478 "/* 0 -> LDST */", 1479 "SET_LDST (0);", 1480 }, 1481 }, 1482 1483 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011", 1484 { 1485 "/* 1 -> LDST */", 1486 "SET_LDST (1);", 1487 "/* (Rn) -> R0 */", 1488 "R[0] = RLAT (R[n]);", 1489 "/* if (interrupt/exception) 0 -> LDST */", 1490 "/* (we don't simulate asynchronous interrupts/exceptions) */", 1491 }, 1492 }, 1493 1494 { "n", "", "movt <REG_N>", "0000nnnn00101001", 1495 { 1496 "R[n] = T;", 1497 }, 1498 }, 1499 { "", "", "movrt <REG_N>", "0000nnnn00111001", 1500 { 1501 "R[n] = (T == 0);", 1502 }, 1503 }, 1504 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001", 1505 { 1506 "int regn = R[n];", 1507 "int e = target_little_endian ? 3 : 0;", 1508 "MA (1);", 1509 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) +", 1510 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));", 1511 "L (0);", 1512 }, 1513 }, 1514 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001", 1515 { 1516 "int regn = R[n];", 1517 "int e = target_little_endian ? 3 : 0;", 1518 "MA (1);", 1519 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) +", 1520 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));", 1521 "R[n] += 4;", 1522 "L (0);", 1523 }, 1524 }, 1525 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111", 1526 { 1527 "MACL = ((int) R[n]) * ((int) R[m]);", 1528 }, 1529 }, 1530 #if 0 /* FIXME: The above cast to int is not really portable. 1531 It should be replaced by a SEXT32 macro. */ 1532 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111", 1533 { 1534 "MACL = R[n] * R[m];", 1535 }, 1536 }, 1537 #endif 1538 1539 /* muls.w - see muls */ 1540 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111", 1541 { 1542 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);", 1543 }, 1544 }, 1545 1546 /* mulu.w - see mulu */ 1547 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110", 1548 { 1549 "MACL = (((unsigned int) (unsigned short) R[n])", 1550 " * ((unsigned int) (unsigned short) R[m]));", 1551 }, 1552 }, 1553 1554 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011", 1555 { 1556 "R[n] = - R[m];", 1557 }, 1558 }, 1559 1560 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010", 1561 { 1562 "ult = -T;", 1563 "SET_SR_T (ult > 0);", 1564 "R[n] = ult - R[m];", 1565 "SET_SR_T (T || (R[n] > ult));", 1566 }, 1567 }, 1568 1569 { "", "", "nop", "0000000000001001", 1570 { 1571 "/* nop */", 1572 }, 1573 }, 1574 1575 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111", 1576 { 1577 "R[n] = ~R[m];", 1578 }, 1579 }, 1580 1581 /* sh4a */ 1582 { "", "n", "icbi @<REG_N>", "0000nnnn11100011", 1583 { 1584 "/* Except for the effect on the cache - which is not simulated -", 1585 " this is like a nop. */", 1586 }, 1587 }, 1588 1589 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011", 1590 { 1591 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */", 1592 "/* FIXME: Cache not implemented */", 1593 }, 1594 }, 1595 1596 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011", 1597 { 1598 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */", 1599 "/* FIXME: Cache not implemented */", 1600 }, 1601 }, 1602 1603 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011", 1604 { 1605 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */", 1606 "/* FIXME: Cache not implemented */", 1607 }, 1608 }, 1609 1610 { "0", "", "or #<imm>,R0", "11001011i8*1....", 1611 { 1612 "R0 |= i;", 1613 }, 1614 }, 1615 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011", 1616 { 1617 "R[n] |= R[m];", 1618 }, 1619 }, 1620 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....", 1621 { 1622 "MA (1);", 1623 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));", 1624 }, 1625 }, 1626 1627 { "", "n", "pref @<REG_N>", "0000nnnn10000011", 1628 { 1629 "/* Except for the effect on the cache - which is not simulated -", 1630 " this is like a nop. */", 1631 }, 1632 }, 1633 1634 /* sh4a */ 1635 { "", "n", "prefi @<REG_N>", "0000nnnn11010011", 1636 { 1637 "/* Except for the effect on the cache - which is not simulated -", 1638 " this is like a nop. */", 1639 }, 1640 }, 1641 1642 /* sh4a */ 1643 { "", "", "synco", "0000000010101011", 1644 { 1645 "/* Except for the effect on the pipeline - which is not simulated -", 1646 " this is like a nop. */", 1647 }, 1648 }, 1649 1650 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100", 1651 { 1652 "ult = R[n] < 0;", 1653 "R[n] = (R[n] << 1) | T;", 1654 "SET_SR_T (ult);", 1655 }, 1656 }, 1657 1658 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101", 1659 { 1660 "ult = R[n] & 1;", 1661 "R[n] = (UR[n] >> 1) | (T << 31);", 1662 "SET_SR_T (ult);", 1663 }, 1664 }, 1665 1666 { "n", "n", "rotl <REG_N>", "0100nnnn00000100", 1667 { 1668 "SET_SR_T (R[n] < 0);", 1669 "R[n] <<= 1;", 1670 "R[n] |= T;", 1671 }, 1672 }, 1673 1674 { "n", "n", "rotr <REG_N>", "0100nnnn00000101", 1675 { 1676 "SET_SR_T (R[n] & 1);", 1677 "R[n] = UR[n] >> 1;", 1678 "R[n] |= (T << 31);", 1679 }, 1680 }, 1681 1682 { "", "", "rte", "0000000000101011", 1683 { 1684 #if 0 1685 /* SH-[12] */ 1686 "int tmp = PC;", 1687 "SET_NIP (PT2H (RLAT (R[15]) + 2));", 1688 "R[15] += 4;", 1689 "SET_SR (RLAT (R[15]) & 0x3f3);", 1690 "R[15] += 4;", 1691 "Delay_Slot (PC + 2);", 1692 #else 1693 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1694 "SET_SR (SSR);", 1695 "SET_NIP (PT2H (SPC));", 1696 "cycles += 2;", 1697 "Delay_Slot (PC + 2);", 1698 #endif 1699 }, 1700 }, 1701 1702 { "", "", "rts", "0000000000001011", 1703 { 1704 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1705 "SET_NIP (PT2H (PR));", 1706 "cycles += 2;", 1707 "Delay_Slot (PC + 2);", 1708 }, 1709 }, 1710 { "", "", "rts/n", "0000000001101011", 1711 { 1712 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1713 "SET_NIP (PT2H (PR));", 1714 }, 1715 }, 1716 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011", 1717 { 1718 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1719 "R0 = R[n];", 1720 "L (0);", 1721 "SET_NIP (PT2H (PR));", 1722 }, 1723 }, 1724 1725 /* sh4a */ 1726 { "", "", "setdmx", "0000000010011000", 1727 { 1728 "saved_state.asregs.sr |= SR_MASK_DMX;" 1729 "saved_state.asregs.sr &= ~SR_MASK_DMY;" 1730 }, 1731 }, 1732 1733 /* sh4a */ 1734 { "", "", "setdmy", "0000000011001000", 1735 { 1736 "saved_state.asregs.sr |= SR_MASK_DMY;" 1737 "saved_state.asregs.sr &= ~SR_MASK_DMX;" 1738 }, 1739 }, 1740 1741 /* sh-dsp */ 1742 { "", "n", "setrc <REG_N>", "0100nnnn00010100", 1743 { 1744 "SET_RC (R[n]);", 1745 }, 1746 }, 1747 { "", "", "setrc #<imm>", "10000010i8*1....", 1748 { 1749 /* It would be more realistic to let loop_start point to some static 1750 memory that contains an illegal opcode and then give a bus error when 1751 the loop is eventually encountered, but it seems not only simpler, 1752 but also more debugging-friendly to just catch the failure here. */ 1753 "if (BUSERROR (RS | RE, maskw))", 1754 " RAISE_EXCEPTION (SIGILL);", 1755 "else {", 1756 " SET_RC (i);", 1757 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);", 1758 " CHECK_INSN_PTR (insn_ptr);", 1759 "}", 1760 }, 1761 }, 1762 1763 { "", "", "sets", "0000000001011000", 1764 { 1765 "SET_SR_S (1);", 1766 }, 1767 }, 1768 1769 { "", "", "sett", "0000000000011000", 1770 { 1771 "SET_SR_T (1);", 1772 }, 1773 }, 1774 1775 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100", 1776 { 1777 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));", 1778 }, 1779 }, 1780 1781 { "n", "n", "shal <REG_N>", "0100nnnn00100000", 1782 { 1783 "SET_SR_T (R[n] < 0);", 1784 "R[n] <<= 1;", 1785 }, 1786 }, 1787 1788 { "n", "n", "shar <REG_N>", "0100nnnn00100001", 1789 { 1790 "SET_SR_T (R[n] & 1);", 1791 "R[n] = R[n] >> 1;", 1792 }, 1793 }, 1794 1795 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101", 1796 { 1797 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));", 1798 }, 1799 }, 1800 1801 { "n", "n", "shll <REG_N>", "0100nnnn00000000", 1802 { 1803 "SET_SR_T (R[n] < 0);", 1804 "R[n] <<= 1;", 1805 }, 1806 }, 1807 1808 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000", 1809 { 1810 "R[n] <<= 2;", 1811 }, 1812 }, 1813 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000", 1814 { 1815 "R[n] <<= 8;", 1816 }, 1817 }, 1818 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000", 1819 { 1820 "R[n] <<= 16;", 1821 }, 1822 }, 1823 1824 { "n", "n", "shlr <REG_N>", "0100nnnn00000001", 1825 { 1826 "SET_SR_T (R[n] & 1);", 1827 "R[n] = UR[n] >> 1;", 1828 }, 1829 }, 1830 1831 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001", 1832 { 1833 "R[n] = UR[n] >> 2;", 1834 }, 1835 }, 1836 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001", 1837 { 1838 "R[n] = UR[n] >> 8;", 1839 }, 1840 }, 1841 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001", 1842 { 1843 "R[n] = UR[n] >> 16;", 1844 }, 1845 }, 1846 1847 { "", "", "sleep", "0000000000011011", 1848 { 1849 "nip += trap (sd, 0xc3, &R0, PC, memory, maskl, maskw, endianw);", 1850 }, 1851 }, 1852 1853 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010", 1854 { 1855 "R[n] = CREG (m);", 1856 }, 1857 }, 1858 1859 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010", 1860 { 1861 "if (SR_MD)", 1862 " R[n] = SGR; /* priv mode */", 1863 "else", 1864 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1865 }, 1866 }, 1867 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010", 1868 { 1869 "if (SR_MD)", 1870 " R[n] = DBR; /* priv mode */", 1871 "else", 1872 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1873 }, 1874 }, 1875 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010", 1876 { 1877 "if (SR_MD)", /* FIXME? */ 1878 " R[n] = TBR; /* priv mode */", 1879 "else", 1880 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1881 }, 1882 }, 1883 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011", 1884 { 1885 "MA (1);", 1886 "R[n] -= 4;", 1887 "WLAT (R[n], CREG (m));", 1888 }, 1889 }, 1890 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010", 1891 { 1892 "if (SR_MD)", 1893 "{ /* priv mode */", 1894 " MA (1);", 1895 " R[n] -= 4;", 1896 " WLAT (R[n], SGR);", 1897 "}", 1898 "else", 1899 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1900 }, 1901 }, 1902 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010", 1903 { 1904 "if (SR_MD)", 1905 "{ /* priv mode */", 1906 " MA (1);", 1907 " R[n] -= 4;", 1908 " WLAT (R[n], DBR);", 1909 "}", 1910 "else", 1911 " RAISE_EXCEPTION (SIGILL); /* user mode */", 1912 }, 1913 }, 1914 1915 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010", 1916 { 1917 "R[n] = SREG (m);", 1918 }, 1919 }, 1920 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010", 1921 { 1922 "MA (1);", 1923 "R[n] -= 4;", 1924 "WLAT (R[n], SREG (m));", 1925 }, 1926 }, 1927 1928 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000", 1929 { 1930 "R[n] -= R[m];", 1931 }, 1932 }, 1933 1934 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010", 1935 { 1936 "ult = R[n] - T;", 1937 "SET_SR_T (ult > R[n]);", 1938 "R[n] = ult - R[m];", 1939 "SET_SR_T (T || (R[n] > ult));", 1940 }, 1941 }, 1942 1943 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011", 1944 { 1945 "ult = R[n] - R[m];", 1946 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);", 1947 "R[n] = ult;", 1948 }, 1949 }, 1950 1951 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000", 1952 { 1953 "R[n] = ((R[m] & 0xffff0000)", 1954 " | ((R[m] << 8) & 0xff00)", 1955 " | ((R[m] >> 8) & 0x00ff));", 1956 }, 1957 }, 1958 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001", 1959 { 1960 "R[n] = (((R[m] << 16) & 0xffff0000)", 1961 " | ((R[m] >> 16) & 0x00ffff));", 1962 }, 1963 }, 1964 1965 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011", 1966 { 1967 "MA (1);", 1968 "ult = RBAT (R[n]);", 1969 "SET_SR_T (ult == 0);", 1970 "WBAT (R[n],ult|0x80);", 1971 }, 1972 }, 1973 1974 { "0", "", "trapa #<imm>", "11000011i8*1....", 1975 { 1976 "long imm = 0xff & i;", 1977 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 1978 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)", 1979 " nip += trap (sd, i, &R0, PC, memory, maskl, maskw, endianw);", 1980 #if 0 1981 "else {", 1982 /* SH-[12] */ 1983 " R[15] -= 4;", 1984 " WLAT (R[15], GET_SR ());", 1985 " R[15] -= 4;", 1986 " WLAT (R[15], PH2T (PC + 2));", 1987 #else 1988 "else if (!SR_BL) {", 1989 " SSR = GET_SR ();", 1990 " SPC = PH2T (PC + 2);", 1991 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);", 1992 " /* FIXME: EXPEVT = 0x00000160; */", 1993 #endif 1994 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));", 1995 "}", 1996 }, 1997 }, 1998 1999 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000", 2000 { 2001 "SET_SR_T ((R[n] & R[m]) == 0);", 2002 }, 2003 }, 2004 { "", "0", "tst #<imm>,R0", "11001000i8*1....", 2005 { 2006 "SET_SR_T ((R0 & i) == 0);", 2007 }, 2008 }, 2009 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....", 2010 { 2011 "MA (1);", 2012 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);", 2013 }, 2014 }, 2015 2016 { "", "0", "xor #<imm>,R0", "11001010i8*1....", 2017 { 2018 "R0 ^= i;", 2019 }, 2020 }, 2021 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010", 2022 { 2023 "R[n] ^= R[m];", 2024 }, 2025 }, 2026 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....", 2027 { 2028 "MA (1);", 2029 "ult = RBAT (GBR+R0);", 2030 "ult ^= i;", 2031 "WBAT (GBR + R0, ult);", 2032 }, 2033 }, 2034 2035 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101", 2036 { 2037 "R[n] = (((R[n] >> 16) & 0xffff)", 2038 " | ((R[m] << 16) & 0xffff0000));", 2039 }, 2040 }, 2041 2042 #if 0 2043 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110", 2044 { 2045 "divl (0, R[n], R[m]);", 2046 }, 2047 }, 2048 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101", 2049 { 2050 "divl (0, R[n], R[m]);", 2051 }, 2052 }, 2053 #endif 2054 2055 {}, 2056 }; 2057 2058 static op movsxy_tab[] = 2059 { 2060 /* If this is disabled, the simulator speeds up by about 12% on a 2061 450 MHz PIII - 9% with ACE_FAST. 2062 Maybe we should have separate simulator loops? */ 2063 #if 1 2064 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000", 2065 { 2066 "MA (1);", 2067 "R[n] -= 2;", 2068 "DSP_R (m) = RSWAT (R[n]) << 16;", 2069 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2070 }, 2071 }, 2072 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100", 2073 { 2074 "MA (1);", 2075 "DSP_R (m) = RSWAT (R[n]) << 16;", 2076 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2077 }, 2078 }, 2079 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000", 2080 { 2081 "MA (1);", 2082 "DSP_R (m) = RSWAT (R[n]) << 16;", 2083 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2084 "R[n] += 2;", 2085 }, 2086 }, 2087 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100", 2088 { 2089 "MA (1);", 2090 "DSP_R (m) = RSWAT (R[n]) << 16;", 2091 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2092 "R[n] += R[8];", 2093 }, 2094 }, 2095 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000", 2096 { 2097 "MA (1);", 2098 "R[n] -= 2;", 2099 "DSP_R (m) = RSWAT (R[n]);", 2100 }, 2101 }, 2102 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100", 2103 { 2104 "MA (1);", 2105 "DSP_R (m) = RSWAT (R[n]);", 2106 }, 2107 }, 2108 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000", 2109 { 2110 "MA (1);", 2111 "DSP_R (m) = RSWAT (R[n]);", 2112 "R[n] += 2;", 2113 }, 2114 }, 2115 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100", 2116 { 2117 "MA (1);", 2118 "DSP_R (m) = RSWAT (R[n]);", 2119 "R[n] += R[8];", 2120 }, 2121 }, 2122 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001", 2123 { 2124 "MA (1);", 2125 "R[n] -= 2;", 2126 "WWAT (R[n], DSP_R (m) >> 16);", 2127 }, 2128 }, 2129 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101", 2130 { 2131 "MA (1);", 2132 "WWAT (R[n], DSP_R (m) >> 16);", 2133 }, 2134 }, 2135 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001", 2136 { 2137 "MA (1);", 2138 "WWAT (R[n], DSP_R (m) >> 16);", 2139 "R[n] += 2;", 2140 }, 2141 }, 2142 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101", 2143 { 2144 "MA (1);", 2145 "WWAT (R[n], DSP_R (m) >> 16);", 2146 "R[n] += R[8];", 2147 }, 2148 }, 2149 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001", 2150 { 2151 "MA (1);", 2152 "R[n] -= 2;", 2153 "WWAT (R[n], SEXT (DSP_R (m)));", 2154 }, 2155 }, 2156 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101", 2157 { 2158 "MA (1);", 2159 "WWAT (R[n], SEXT (DSP_R (m)));", 2160 }, 2161 }, 2162 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001", 2163 { 2164 "MA (1);", 2165 "WWAT (R[n], SEXT (DSP_R (m)));", 2166 "R[n] += 2;", 2167 }, 2168 }, 2169 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101", 2170 { 2171 "MA (1);", 2172 "WWAT (R[n], SEXT (DSP_R (m)));", 2173 "R[n] += R[8];", 2174 }, 2175 }, 2176 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010", 2177 { 2178 "MA (1);", 2179 "R[n] -= 4;", 2180 "DSP_R (m) = RLAT (R[n]);", 2181 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2182 }, 2183 }, 2184 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110", 2185 { 2186 "MA (1);", 2187 "DSP_R (m) = RLAT (R[n]);", 2188 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2189 }, 2190 }, 2191 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010", 2192 { 2193 "MA (1);", 2194 "DSP_R (m) = RLAT (R[n]);", 2195 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2196 "R[n] += 4;", 2197 }, 2198 }, 2199 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110", 2200 { 2201 "MA (1);", 2202 "DSP_R (m) = RLAT (R[n]);", 2203 "DSP_GRD (m) = SIGN32 (DSP_R (m));", 2204 "R[n] += R[8];", 2205 }, 2206 }, 2207 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011", 2208 { 2209 "MA (1);", 2210 "R[n] -= 4;", 2211 "WLAT (R[n], DSP_R (m));", 2212 }, 2213 }, 2214 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111", 2215 { 2216 "MA (1);", 2217 "WLAT (R[n], DSP_R (m));", 2218 }, 2219 }, 2220 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011", 2221 { 2222 "MA (1);", 2223 "WLAT (R[n], DSP_R (m));", 2224 "R[n] += 4;", 2225 }, 2226 }, 2227 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111", 2228 { 2229 "MA (1);", 2230 "WLAT (R[n], DSP_R (m));", 2231 "R[n] += R[8];", 2232 }, 2233 }, 2234 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011", 2235 { 2236 "MA (1);", 2237 "R[n] -= 4;", 2238 "WLAT (R[n], SEXT (DSP_R (m)));", 2239 }, 2240 }, 2241 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111", 2242 { 2243 "MA (1);", 2244 "WLAT (R[n], SEXT (DSP_R (m)));", 2245 }, 2246 }, 2247 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011", 2248 { 2249 "MA (1);", 2250 "WLAT (R[n], SEXT (DSP_R (m)));", 2251 "R[n] += 4;", 2252 }, 2253 }, 2254 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111", 2255 { 2256 "MA (1);", 2257 "WLAT (R[n], SEXT (DSP_R (m)));", 2258 "R[n] += R[8];", 2259 }, 2260 }, 2261 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??", 2262 { 2263 "DSP_R (m) = RSWAT (R[n]) << 16;", 2264 "if (iword & 3)", 2265 " {", 2266 " iword &= 0xfd53; goto top;", 2267 " }", 2268 }, 2269 }, 2270 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100", 2271 { 2272 "DSP_R (m) = RLAT (R[n]);", 2273 }, 2274 }, 2275 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??", 2276 { 2277 "DSP_R (m) = RSWAT (R[n]) << 16;", 2278 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;", 2279 "if (iword & 3)", 2280 " {", 2281 " iword &= 0xfd53; goto top;", 2282 " }", 2283 }, 2284 }, 2285 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000", 2286 { 2287 "DSP_R (m) = RLAT (R[n]);", 2288 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;", 2289 }, 2290 }, 2291 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??", 2292 { 2293 "DSP_R (m) = RSWAT (R[n]) << 16;", 2294 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];", 2295 "if (iword & 3)", 2296 " {", 2297 " iword &= 0xfd53; goto top;", 2298 " }", 2299 }, 2300 }, 2301 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100", 2302 { 2303 "DSP_R (m) = RLAT (R[n]);", 2304 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];", 2305 }, 2306 }, 2307 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??", 2308 { 2309 "WWAT (R[n], DSP_R (m) >> 16);", 2310 "if (iword & 3)", 2311 " {", 2312 " iword &= 0xfd53; goto top;", 2313 " }", 2314 }, 2315 }, 2316 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100", 2317 { 2318 "WLAT (R[n], DSP_R (m));", 2319 }, 2320 }, 2321 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??", 2322 { 2323 "WWAT (R[n], DSP_R (m) >> 16);", 2324 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;", 2325 "if (iword & 3)", 2326 " {", 2327 " iword &= 0xfd53; goto top;", 2328 " }", 2329 }, 2330 }, 2331 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000", 2332 { 2333 "WLAT (R[n], DSP_R (m));", 2334 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;", 2335 }, 2336 }, 2337 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??", 2338 { 2339 "WWAT (R[n], DSP_R (m) >> 16);", 2340 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];", 2341 "if (iword & 3)", 2342 " {", 2343 " iword &= 0xfd53; goto top;", 2344 " }", 2345 }, 2346 }, 2347 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100", 2348 { 2349 "WLAT (R[n], DSP_R (m));", 2350 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];", 2351 }, 2352 }, 2353 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001", 2354 { 2355 "DSP_R (m) = RSWAT (R[n]) << 16;", 2356 }, 2357 }, 2358 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010", 2359 { 2360 "DSP_R (m) = RSWAT (R[n]) << 16;", 2361 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;", 2362 }, 2363 }, 2364 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011", 2365 { 2366 "DSP_R (m) = RSWAT (R[n]) << 16;", 2367 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];", 2368 }, 2369 }, 2370 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001", 2371 { 2372 "WWAT (R[n], DSP_R (m) >> 16);", 2373 }, 2374 }, 2375 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010", 2376 { 2377 "WWAT (R[n], DSP_R (m) >> 16);", 2378 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;", 2379 }, 2380 }, 2381 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011", 2382 { 2383 "WWAT (R[n], DSP_R (m) >> 16);", 2384 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];", 2385 }, 2386 }, 2387 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001", 2388 { 2389 "DSP_R (m) = RLAT (R[n]);", 2390 }, 2391 }, 2392 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010", 2393 { 2394 "DSP_R (m) = RLAT (R[n]);", 2395 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;", 2396 }, 2397 }, 2398 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011", 2399 { 2400 "DSP_R (m) = RLAT (R[n]);", 2401 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];", 2402 }, 2403 }, 2404 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001", 2405 { 2406 "WLAT (R[n], DSP_R (m));", 2407 }, 2408 }, 2409 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010", 2410 { 2411 "WLAT (R[n], DSP_R (m));", 2412 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;", 2413 }, 2414 }, 2415 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011", 2416 { 2417 "WLAT (R[n], DSP_R (m));", 2418 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];", 2419 }, 2420 }, 2421 { "", "", "nopx nopy", "1111000000000000", 2422 { 2423 "/* nop */", 2424 }, 2425 }, 2426 { "", "", "ppi", "1111100000000000", 2427 { 2428 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();", 2429 "ppi_insn (RIAT (nip));", 2430 "SET_NIP (nip + 2);", 2431 "iword &= 0xf7ff; goto top;", 2432 }, 2433 }, 2434 #endif 2435 {}, 2436 }; 2437 2438 static op ppi_tab[] = 2439 { 2440 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz", 2441 { 2442 "int Sz = DSP_R (z) & 0xffff0000;", 2443 "", 2444 "if (i <= 16)", 2445 " res = Sz << i;", 2446 "else if (i >= 128 - 16)", 2447 " res = (unsigned) Sz >> (128 - i); /* no sign extension */", 2448 "else", 2449 " {", 2450 " RAISE_EXCEPTION (SIGILL);", 2451 " return;", 2452 " }", 2453 "res &= 0xffff0000;", 2454 "res_grd = 0;", 2455 "goto logical;", 2456 }, 2457 }, 2458 { "","", "psha #<imm>,dz", "00010iiim32.zzzz", 2459 { 2460 "int Sz = DSP_R (z);", 2461 "int Sz_grd = GET_DSP_GRD (z);", 2462 "", 2463 "if (i <= 32)", 2464 " {", 2465 " if (i == 32)", 2466 " {", 2467 " res = 0;", 2468 " res_grd = Sz;", 2469 " }", 2470 " else", 2471 " {", 2472 " res = Sz << i;", 2473 " res_grd = Sz_grd << i | (unsigned) Sz >> (32 - i);", 2474 " }", 2475 " res_grd = SEXT (res_grd);", 2476 " carry = res_grd & 1;", 2477 " }", 2478 "else if (i >= 96)", 2479 " {", 2480 " i = 128 - i;", 2481 " if (i == 32)", 2482 " {", 2483 " res_grd = SIGN32 (Sz_grd);", 2484 " res = Sz_grd;", 2485 " }", 2486 " else", 2487 " {", 2488 " res = Sz >> i | Sz_grd << (32 - i);", 2489 " res_grd = Sz_grd >> i;", 2490 " }", 2491 " carry = Sz >> (i - 1) & 1;", 2492 " }", 2493 "else", 2494 " {", 2495 " RAISE_EXCEPTION (SIGILL);", 2496 " return;", 2497 " }", 2498 "COMPUTE_OVERFLOW;", 2499 "greater_equal = 0;", 2500 }, 2501 }, 2502 { "","", "pmuls Se,Sf,Dg", "0100eeff0000gg00", 2503 { 2504 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;", 2505 "if (res == 0x80000000)", 2506 " res = 0x7fffffff;", 2507 "DSP_R (g) = res;", 2508 "DSP_GRD (g) = SIGN32 (res);", 2509 "return;", 2510 }, 2511 }, 2512 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu", 2513 { 2514 "int Sx = DSP_R (x);", 2515 "int Sx_grd = GET_DSP_GRD (x);", 2516 "int Sy = DSP_R (y);", 2517 "int Sy_grd = SIGN32 (Sy);", 2518 "", 2519 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;", 2520 "if (res == 0x80000000)", 2521 " res = 0x7fffffff;", 2522 "DSP_R (g) = res;", 2523 "DSP_GRD (g) = SIGN32 (res);", 2524 "", 2525 "z = u;", 2526 "res = Sx - Sy;", 2527 "carry = (unsigned) res > (unsigned) Sx;", 2528 "res_grd = Sx_grd - Sy_grd - carry;", 2529 "COMPUTE_OVERFLOW;", 2530 "ADD_SUB_GE;", 2531 }, 2532 }, 2533 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu", 2534 { 2535 "int Sx = DSP_R (x);", 2536 "int Sx_grd = GET_DSP_GRD (x);", 2537 "int Sy = DSP_R (y);", 2538 "int Sy_grd = SIGN32 (Sy);", 2539 "", 2540 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;", 2541 "if (res == 0x80000000)", 2542 " res = 0x7fffffff;", 2543 "DSP_R (g) = res;", 2544 "DSP_GRD (g) = SIGN32 (res);", 2545 "", 2546 "z = u;", 2547 "res = Sx + Sy;", 2548 "carry = (unsigned) res < (unsigned) Sx;", 2549 "res_grd = Sx_grd + Sy_grd + carry;", 2550 "COMPUTE_OVERFLOW;", 2551 }, 2552 }, 2553 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz", 2554 { 2555 "int Sx = DSP_R (x);", 2556 "int Sx_grd = GET_DSP_GRD (x);", 2557 "int Sy = DSP_R (y);", 2558 "int Sy_grd = SIGN32 (Sy);", 2559 "", 2560 "res = Sx - Sy - (DSR & 1);", 2561 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);", 2562 "res_grd = Sx_grd + Sy_grd + carry;", 2563 "COMPUTE_OVERFLOW;", 2564 "ADD_SUB_GE;", 2565 "DSR &= ~0xf1;\n", 2566 "if (res || res_grd)\n", 2567 " DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n", 2568 "else\n", 2569 " DSR |= DSR_MASK_Z | overflow;\n", 2570 "DSR |= carry;\n", 2571 "goto assign_z;\n", 2572 }, 2573 }, 2574 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz", 2575 { 2576 "int Sx = DSP_R (x);", 2577 "int Sx_grd = GET_DSP_GRD (x);", 2578 "int Sy = DSP_R (y);", 2579 "int Sy_grd = SIGN32 (Sy);", 2580 "", 2581 "res = Sx + Sy + (DSR & 1);", 2582 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);", 2583 "res_grd = Sx_grd + Sy_grd + carry;", 2584 "COMPUTE_OVERFLOW;", 2585 "ADD_SUB_GE;", 2586 "DSR &= ~0xf1;\n", 2587 "if (res || res_grd)\n", 2588 " DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n", 2589 "else\n", 2590 " DSR |= DSR_MASK_Z | overflow;\n", 2591 "DSR |= carry;\n", 2592 "goto assign_z;\n", 2593 }, 2594 }, 2595 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz", 2596 { 2597 "int Sx = DSP_R (x);", 2598 "int Sx_grd = GET_DSP_GRD (x);", 2599 "int Sy = DSP_R (y);", 2600 "int Sy_grd = SIGN32 (Sy);", 2601 "", 2602 "z = 17; /* Ignore result. */", 2603 "res = Sx - Sy;", 2604 "carry = (unsigned) res > (unsigned) Sx;", 2605 "res_grd = Sx_grd - Sy_grd - carry;", 2606 "COMPUTE_OVERFLOW;", 2607 "ADD_SUB_GE;", 2608 }, 2609 }, 2610 { "","", "pwsb Sx,Sy,Dz", "10100100....zzzz", 2611 { 2612 "return;", 2613 }, 2614 }, 2615 { "","", "pwad Sx,Sy,Dz", "10110100....zzzz", 2616 { 2617 "return;", 2618 }, 2619 }, 2620 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz", 2621 { 2622 "/* FIXME: duplicate code pabs. */", 2623 "res = DSP_R (x);", 2624 "res_grd = GET_DSP_GRD (x);", 2625 "if (res >= 0)", 2626 " carry = 0;", 2627 "else", 2628 " {", 2629 " res = -res;", 2630 " carry = (res != 0); /* The manual has a bug here. */", 2631 " res_grd = -res_grd - carry;", 2632 " }", 2633 "COMPUTE_OVERFLOW;", 2634 "/* ??? The re-computing of overflow after", 2635 " saturation processing is specific to pabs. */", 2636 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;", 2637 "ADD_SUB_GE;", 2638 }, 2639 }, 2640 { "","", "pabs Sx,Dz", "10001000xx..zzzz", 2641 { 2642 "res = DSP_R (x);", 2643 "res_grd = GET_DSP_GRD (x);", 2644 "if (res >= 0)", 2645 " carry = 0;", 2646 "else", 2647 " {", 2648 " res = -res;", 2649 " carry = (res != 0); /* The manual has a bug here. */", 2650 " res_grd = -res_grd - carry;", 2651 " }", 2652 "COMPUTE_OVERFLOW;", 2653 "/* ??? The re-computing of overflow after", 2654 " saturation processing is specific to pabs. */", 2655 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;", 2656 "ADD_SUB_GE;", 2657 }, 2658 }, 2659 2660 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz", 2661 { 2662 "/* FIXME: duplicate code prnd. */", 2663 "int Sx = DSP_R (x);", 2664 "int Sx_grd = GET_DSP_GRD (x);", 2665 "", 2666 "res = (Sx + 0x8000) & 0xffff0000;", 2667 "carry = (unsigned) res < (unsigned) Sx;", 2668 "res_grd = Sx_grd + carry;", 2669 "COMPUTE_OVERFLOW;", 2670 "ADD_SUB_GE;", 2671 }, 2672 }, 2673 { "","", "prnd Sx,Dz", "10011000xx..zzzz", 2674 { 2675 "int Sx = DSP_R (x);", 2676 "int Sx_grd = GET_DSP_GRD (x);", 2677 "", 2678 "res = (Sx + 0x8000) & 0xffff0000;", 2679 "carry = (unsigned) res < (unsigned) Sx;", 2680 "res_grd = Sx_grd + carry;", 2681 "COMPUTE_OVERFLOW;", 2682 "ADD_SUB_GE;", 2683 }, 2684 }, 2685 2686 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz", 2687 { 2688 "/* FIXME: duplicate code pabs. */", 2689 "res = DSP_R (y);", 2690 "res_grd = 0;", 2691 "overflow = 0;", 2692 "greater_equal = DSR_MASK_G;", 2693 "if (res >= 0)", 2694 " carry = 0;", 2695 "else", 2696 " {", 2697 " res = -res;", 2698 " carry = 1;", 2699 " if (res < 0)", 2700 " {", 2701 " if (S)", 2702 " res = 0x7fffffff;", 2703 " else", 2704 " {", 2705 " overflow = DSR_MASK_V;", 2706 " greater_equal = 0;", 2707 " }", 2708 " }", 2709 " }", 2710 }, 2711 }, 2712 { "","", "pabs Sy,Dz", "10101000..yyzzzz", 2713 { 2714 "res = DSP_R (y);", 2715 "res_grd = 0;", 2716 "overflow = 0;", 2717 "greater_equal = DSR_MASK_G;", 2718 "if (res >= 0)", 2719 " carry = 0;", 2720 "else", 2721 " {", 2722 " res = -res;", 2723 " carry = 1;", 2724 " if (res < 0)", 2725 " {", 2726 " if (S)", 2727 " res = 0x7fffffff;", 2728 " else", 2729 " {", 2730 " overflow = DSR_MASK_V;", 2731 " greater_equal = 0;", 2732 " }", 2733 " }", 2734 " }", 2735 }, 2736 }, 2737 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz", 2738 { 2739 "/* FIXME: duplicate code prnd. */", 2740 "int Sy = DSP_R (y);", 2741 "int Sy_grd = SIGN32 (Sy);", 2742 "", 2743 "res = (Sy + 0x8000) & 0xffff0000;", 2744 "carry = (unsigned) res < (unsigned) Sy;", 2745 "res_grd = Sy_grd + carry;", 2746 "COMPUTE_OVERFLOW;", 2747 "ADD_SUB_GE;", 2748 }, 2749 }, 2750 { "","", "prnd Sy,Dz", "10111000..yyzzzz", 2751 { 2752 "int Sy = DSP_R (y);", 2753 "int Sy_grd = SIGN32 (Sy);", 2754 "", 2755 "res = (Sy + 0x8000) & 0xffff0000;", 2756 "carry = (unsigned) res < (unsigned) Sy;", 2757 "res_grd = Sy_grd + carry;", 2758 "COMPUTE_OVERFLOW;", 2759 "ADD_SUB_GE;", 2760 }, 2761 }, 2762 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz", 2763 { 2764 "int Sx = DSP_R (x) & 0xffff0000;", 2765 "int Sy = DSP_R (y) >> 16 & 0x7f;", 2766 "", 2767 "if (Sy <= 16)", 2768 " res = Sx << Sy;", 2769 "else if (Sy >= 128 - 16)", 2770 " res = (unsigned) Sx >> (128 - Sy); /* no sign extension */", 2771 "else", 2772 " {", 2773 " RAISE_EXCEPTION (SIGILL);", 2774 " return;", 2775 " }", 2776 "goto cond_logical;", 2777 }, 2778 }, 2779 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz", 2780 { 2781 "int Sx = DSP_R (x);", 2782 "int Sx_grd = GET_DSP_GRD (x);", 2783 "int Sy = DSP_R (y) >> 16 & 0x7f;", 2784 "", 2785 "if (Sy <= 32)", 2786 " {", 2787 " if (Sy == 32)", 2788 " {", 2789 " res = 0;", 2790 " res_grd = Sx;", 2791 " }", 2792 " else", 2793 " {", 2794 " res = Sx << Sy;", 2795 " res_grd = Sx_grd << Sy | (unsigned) Sx >> (32 - Sy);", 2796 " }", 2797 " res_grd = SEXT (res_grd);", 2798 " carry = res_grd & 1;", 2799 " }", 2800 "else if (Sy >= 96)", 2801 " {", 2802 " Sy = 128 - Sy;", 2803 " if (Sy == 32)", 2804 " {", 2805 " res_grd = SIGN32 (Sx_grd);", 2806 " res = Sx_grd;", 2807 " }", 2808 " else", 2809 " {", 2810 " res = Sx >> Sy | Sx_grd << (32 - Sy);", 2811 " res_grd = Sx_grd >> Sy;", 2812 " }", 2813 " carry = Sx >> (Sy - 1) & 1;", 2814 " }", 2815 "else", 2816 " {", 2817 " RAISE_EXCEPTION (SIGILL);", 2818 " return;", 2819 " }", 2820 "COMPUTE_OVERFLOW;", 2821 "greater_equal = 0;", 2822 }, 2823 }, 2824 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz", 2825 { 2826 "int Sx = DSP_R (x);", 2827 "int Sx_grd = GET_DSP_GRD (x);", 2828 "int Sy = DSP_R (y);", 2829 "int Sy_grd = SIGN32 (Sy);", 2830 "", 2831 "res = Sx - Sy;", 2832 "carry = (unsigned) res > (unsigned) Sx;", 2833 "res_grd = Sx_grd - Sy_grd - carry;", 2834 "COMPUTE_OVERFLOW;", 2835 "ADD_SUB_GE;", 2836 }, 2837 }, 2838 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz", 2839 { 2840 "int Sx = DSP_R (x);", 2841 "int Sx_grd = GET_DSP_GRD (x);", 2842 "int Sy = DSP_R (y);", 2843 "int Sy_grd = SIGN32 (Sy);", 2844 "", 2845 "res = Sy - Sx;", 2846 "carry = (unsigned) res > (unsigned) Sy;", 2847 "res_grd = Sy_grd - Sx_grd - carry;", 2848 "COMPUTE_OVERFLOW;", 2849 "ADD_SUB_GE;", 2850 }, 2851 }, 2852 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz", 2853 { 2854 "int Sx = DSP_R (x);", 2855 "int Sx_grd = GET_DSP_GRD (x);", 2856 "int Sy = DSP_R (y);", 2857 "int Sy_grd = SIGN32 (Sy);", 2858 "", 2859 "res = Sx + Sy;", 2860 "carry = (unsigned) res < (unsigned) Sx;", 2861 "res_grd = Sx_grd + Sy_grd + carry;", 2862 "COMPUTE_OVERFLOW;", 2863 "ADD_SUB_GE;", 2864 }, 2865 }, 2866 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz", 2867 { 2868 "res = DSP_R (x) & DSP_R (y);", 2869 "cond_logical:", 2870 "res &= 0xffff0000;", 2871 "res_grd = 0;", 2872 "if (iword & 0x200)\n", 2873 " goto assign_z;\n", 2874 "logical:", 2875 "carry = 0;", 2876 "overflow = 0;", 2877 "greater_equal = 0;", 2878 "DSR &= ~0xf1;\n", 2879 "if (res)\n", 2880 " DSR |= res >> 26 & DSR_MASK_N;\n", 2881 "else\n", 2882 " DSR |= DSR_MASK_Z;\n", 2883 "goto assign_dc;\n", 2884 }, 2885 }, 2886 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz", 2887 { 2888 "res = DSP_R (x) ^ DSP_R (y);", 2889 "goto cond_logical;", 2890 }, 2891 }, 2892 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz", 2893 { 2894 "res = DSP_R (x) | DSP_R (y);", 2895 "goto cond_logical;", 2896 }, 2897 }, 2898 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz", 2899 { 2900 "int Sx = DSP_R (x);", 2901 "int Sx_grd = GET_DSP_GRD (x);", 2902 "", 2903 "res = Sx - 0x10000;", 2904 "carry = Sx < (INT_MIN + 0x10000);", 2905 "res_grd = Sx_grd - carry;", 2906 "COMPUTE_OVERFLOW;", 2907 "ADD_SUB_GE;", 2908 "res &= 0xffff0000;", 2909 }, 2910 }, 2911 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz", 2912 { 2913 "int Sx = DSP_R (x);", 2914 "int Sx_grd = GET_DSP_GRD (x);", 2915 "", 2916 "res = Sx + 0x10000;", 2917 "carry = Sx > (INT_MAX - 0x10000);", 2918 "res_grd = Sx_grd + carry;", 2919 "COMPUTE_OVERFLOW;", 2920 "ADD_SUB_GE;", 2921 "res &= 0xffff0000;", 2922 }, 2923 }, 2924 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz", 2925 { 2926 "int Sy = DSP_R (y);", 2927 "int Sy_grd = SIGN32 (Sy);", 2928 "", 2929 "res = Sy - 0x10000;", 2930 "carry = Sy < (INT_MIN + 0x10000);", 2931 "res_grd = Sy_grd - carry;", 2932 "COMPUTE_OVERFLOW;", 2933 "ADD_SUB_GE;", 2934 "res &= 0xffff0000;", 2935 }, 2936 }, 2937 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz", 2938 { 2939 "int Sy = DSP_R (y);", 2940 "int Sy_grd = SIGN32 (Sy);", 2941 "", 2942 "res = Sy + 0x10000;", 2943 "carry = Sy > (INT_MAX - 0x10000);", 2944 "res_grd = Sy_grd + carry;", 2945 "COMPUTE_OVERFLOW;", 2946 "ADD_SUB_GE;", 2947 "res &= 0xffff0000;", 2948 }, 2949 }, 2950 { "","", "(if cc) pclr Dz", "100011cc....zzzz", 2951 { 2952 "res = 0;", 2953 "res_grd = 0;", 2954 "carry = 0;", 2955 "overflow = 0;", 2956 "greater_equal = 1;", 2957 }, 2958 }, 2959 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu", 2960 { 2961 "/* Do multiply. */", 2962 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;", 2963 "if (res == 0x80000000)", 2964 " res = 0x7fffffff;", 2965 "DSP_R (g) = res;", 2966 "DSP_GRD (g) = SIGN32 (res);", 2967 "/* FIXME: update DSR based on results of multiply! */", 2968 "", 2969 "/* Do clr. */", 2970 "z = u;", 2971 "res = 0;", 2972 "res_grd = 0;", 2973 "goto assign_z;", 2974 }, 2975 }, 2976 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz", 2977 { 2978 "unsigned Sx = DSP_R (x);", 2979 "int Sx_grd = GET_DSP_GRD (x);", 2980 "int i = 16;", 2981 "", 2982 "if (Sx_grd < 0)", 2983 " {", 2984 " Sx_grd = ~Sx_grd;", 2985 " Sx = ~Sx;", 2986 " }", 2987 "if (Sx_grd)", 2988 " {", 2989 " Sx = Sx_grd;", 2990 " res = -2;", 2991 " }", 2992 "else if (Sx)", 2993 " res = 30;", 2994 "else", 2995 " res = 31;", 2996 "do", 2997 " {", 2998 " if (Sx & ((unsigned)~0 << i))", 2999 " {", 3000 " res -= i;", 3001 " Sx >>= i;", 3002 " }", 3003 " }", 3004 "while (i >>= 1);", 3005 "res <<= 16;", 3006 "res_grd = SIGN32 (res);", 3007 "carry = 0;", 3008 "overflow = 0;", 3009 "ADD_SUB_GE;", 3010 }, 3011 }, 3012 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz", 3013 { 3014 "unsigned Sy = DSP_R (y);", 3015 "int i = 16;", 3016 "", 3017 "if (Sy < 0)", 3018 " Sy = ~Sy;", 3019 "Sy <<= 1;", 3020 "res = 31;", 3021 "do", 3022 " {", 3023 " if (Sy & ((unsigned)~0 << i))", 3024 " {", 3025 " res -= i;", 3026 " Sy >>= i;", 3027 " }", 3028 " }", 3029 "while (i >>= 1);", 3030 "res <<= 16;", 3031 "res_grd = SIGN32 (res);", 3032 "carry = 0;", 3033 "overflow = 0;", 3034 "ADD_SUB_GE;", 3035 }, 3036 }, 3037 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz", 3038 { 3039 "int Sx = DSP_R (x);", 3040 "int Sx_grd = GET_DSP_GRD (x);", 3041 "", 3042 "res = 0 - Sx;", 3043 "carry = res != 0;", 3044 "res_grd = 0 - Sx_grd - carry;", 3045 "COMPUTE_OVERFLOW;", 3046 "ADD_SUB_GE;", 3047 }, 3048 }, 3049 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz", 3050 { 3051 "res = DSP_R (x);", 3052 "res_grd = GET_DSP_GRD (x);", 3053 "carry = 0;", 3054 "COMPUTE_OVERFLOW;", 3055 "ADD_SUB_GE;", 3056 }, 3057 }, 3058 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz", 3059 { 3060 "int Sy = DSP_R (y);", 3061 "int Sy_grd = SIGN32 (Sy);", 3062 "", 3063 "res = 0 - Sy;", 3064 "carry = res != 0;", 3065 "res_grd = 0 - Sy_grd - carry;", 3066 "COMPUTE_OVERFLOW;", 3067 "ADD_SUB_GE;", 3068 }, 3069 }, 3070 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz", 3071 { 3072 "res = DSP_R (y);", 3073 "res_grd = SIGN32 (res);", 3074 "carry = 0;", 3075 "COMPUTE_OVERFLOW;", 3076 "ADD_SUB_GE;", 3077 }, 3078 }, 3079 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz", 3080 { 3081 "res = MACH;", 3082 "res_grd = SIGN32 (res);", 3083 "goto assign_z;", 3084 }, 3085 }, 3086 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz", 3087 { 3088 "res = MACL;", 3089 "res_grd = SIGN32 (res);", 3090 "goto assign_z;", 3091 }, 3092 }, 3093 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz", 3094 { 3095 "if (0xa05f >> z & 1)", 3096 " RAISE_EXCEPTION (SIGILL);", 3097 "else", 3098 " MACH = DSP_R (z);", 3099 "return;", 3100 }, 3101 }, 3102 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz", 3103 { 3104 "if (0xa05f >> z & 1)", 3105 " RAISE_EXCEPTION (SIGILL);", 3106 "else", 3107 " MACL = DSP_R (z);", 3108 "return;", 3109 }, 3110 }, 3111 /* sh4a */ 3112 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz", 3113 { 3114 "int Sx = DSP_R (x);", 3115 "", 3116 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);", 3117 "res_grd = GET_DSP_GRD (x);", 3118 "carry = 0;", 3119 "overflow = 0;", 3120 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;", 3121 }, 3122 }, 3123 /* sh4a */ 3124 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz", 3125 { 3126 "int Sy = DSP_R (y);", 3127 "", 3128 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);", 3129 "res_grd = SIGN32 (Sy);", 3130 "carry = 0;", 3131 "overflow = 0;", 3132 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;", 3133 }, 3134 }, 3135 3136 {}, 3137 }; 3138 3139 static int 3140 qfunc (const void *va, const void *vb) 3141 { 3142 const op *a = va; 3143 const op *b = vb; 3144 char bufa[9]; 3145 char bufb[9]; 3146 int diff; 3147 3148 memcpy (bufa, a->code, 4); 3149 memcpy (bufa + 4, a->code + 12, 4); 3150 bufa[8] = 0; 3151 3152 memcpy (bufb, b->code, 4); 3153 memcpy (bufb + 4, b->code + 12, 4); 3154 bufb[8] = 0; 3155 diff = strcmp (bufa, bufb); 3156 /* Stabilize the sort, so that later entries can override more general 3157 preceding entries. */ 3158 return diff ? diff : a - b; 3159 } 3160 3161 static void 3162 sorttab (void) 3163 { 3164 op *p = tab; 3165 int len = 0; 3166 3167 while (p->name) 3168 { 3169 p++; 3170 len++; 3171 } 3172 qsort (tab, len, sizeof (*p), qfunc); 3173 } 3174 3175 static void 3176 gengastab (void) 3177 { 3178 op *p; 3179 sorttab (); 3180 for (p = tab; p->name; p++) 3181 { 3182 printf ("%s %-30s\n", p->code, p->name); 3183 } 3184 } 3185 3186 static unsigned short table[1 << 16]; 3187 3188 static int warn_conflicts = 0; 3189 3190 static void 3191 conflict_warn (int val, int i) 3192 { 3193 int ix, key; 3194 int j = table[val]; 3195 3196 fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n", 3197 val, i, table[val]); 3198 3199 for (ix = ARRAY_SIZE (tab); ix >= 0; ix--) 3200 if (tab[ix].index == i || tab[ix].index == j) 3201 { 3202 key = ((tab[ix].code[0] - '0') << 3) + 3203 ((tab[ix].code[1] - '0') << 2) + 3204 ((tab[ix].code[2] - '0') << 1) + 3205 ((tab[ix].code[3] - '0')); 3206 3207 if (val >> 12 == key) 3208 fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name); 3209 } 3210 3211 for (ix = ARRAY_SIZE (movsxy_tab); ix >= 0; ix--) 3212 if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j) 3213 { 3214 key = ((movsxy_tab[ix].code[0] - '0') << 3) + 3215 ((movsxy_tab[ix].code[1] - '0') << 2) + 3216 ((movsxy_tab[ix].code[2] - '0') << 1) + 3217 ((movsxy_tab[ix].code[3] - '0')); 3218 3219 if (val >> 12 == key) 3220 fprintf (stderr, " %s -- %s\n", 3221 movsxy_tab[ix].code, movsxy_tab[ix].name); 3222 } 3223 3224 for (ix = ARRAY_SIZE (ppi_tab); ix >= 0; ix--) 3225 if (ppi_tab[ix].index == i || ppi_tab[ix].index == j) 3226 { 3227 key = ((ppi_tab[ix].code[0] - '0') << 3) + 3228 ((ppi_tab[ix].code[1] - '0') << 2) + 3229 ((ppi_tab[ix].code[2] - '0') << 1) + 3230 ((ppi_tab[ix].code[3] - '0')); 3231 3232 if (val >> 12 == key) 3233 fprintf (stderr, " %s -- %s\n", 3234 ppi_tab[ix].code, ppi_tab[ix].name); 3235 } 3236 } 3237 3238 /* Take an opcode, expand all varying fields in it out and fill all the 3239 right entries in 'table' with the opcode index. */ 3240 3241 static void 3242 expand_opcode (int val, int i, const char *s) 3243 { 3244 if (*s == 0) 3245 { 3246 if (warn_conflicts && table[val] != 0) 3247 conflict_warn (val, i); 3248 table[val] = i; 3249 } 3250 else 3251 { 3252 int j = 0, m = 0; 3253 3254 switch (s[0]) 3255 { 3256 default: 3257 fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]); 3258 exit (1); 3259 case '0': 3260 case '1': 3261 /* Consume an arbitrary number of ones and zeros. */ 3262 do { 3263 j = (j << 1) + (s[m++] - '0'); 3264 } while (s[m] == '0' || s[m] == '1'); 3265 expand_opcode ((val << m) | j, i, s + m); 3266 break; 3267 case 'N': /* NN -- four-way fork */ 3268 for (j = 0; j < 4; j++) 3269 expand_opcode ((val << 2) | j, i, s + 2); 3270 break; 3271 case 'x': /* xx or xy -- two-way or four-way fork */ 3272 for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1)) 3273 expand_opcode ((val << 2) | j, i, s + 2); 3274 break; 3275 case 'y': /* yy or yx -- two-way or four-way fork */ 3276 for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++) 3277 expand_opcode ((val << 2) | j, i, s + 2); 3278 break; 3279 case '?': /* Seven-way "wildcard" fork for movxy */ 3280 expand_opcode ((val << 2), i, s + 2); 3281 for (j = 1; j < 4; j++) 3282 { 3283 expand_opcode ((val << 2) | j, i, s + 2); 3284 expand_opcode ((val << 2) | (j + 16), i, s + 2); 3285 } 3286 break; 3287 case 'i': /* eg. "i8*1" */ 3288 case '.': /* "...." is a wildcard */ 3289 case 'n': 3290 case 'm': 3291 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */ 3292 for (j = 0; j < 16; j++) 3293 expand_opcode ((val << 4) | j, i, s + 4); 3294 break; 3295 case 'e': 3296 /* eeee -- even numbered register: 3297 8 way fork. */ 3298 for (j = 0; j < 15; j += 2) 3299 expand_opcode ((val << 4) | j, i, s + 4); 3300 break; 3301 case 'M': 3302 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G: 3303 MMMM -- 10-way fork */ 3304 expand_opcode ((val << 4) | 5, i, s + 4); 3305 for (j = 7; j < 16; j++) 3306 expand_opcode ((val << 4) | j, i, s + 4); 3307 break; 3308 case 'G': 3309 /* A1G, A0G: 3310 GGGG -- two-way fork */ 3311 for (j = 13; j <= 15; j +=2) 3312 expand_opcode ((val << 4) | j, i, s + 4); 3313 break; 3314 case 's': 3315 /* ssss -- 10-way fork */ 3316 /* System registers mach, macl, pr: */ 3317 for (j = 0; j < 3; j++) 3318 expand_opcode ((val << 4) | j, i, s + 4); 3319 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */ 3320 for (j = 5; j < 12; j++) 3321 expand_opcode ((val << 4) | j, i, s + 4); 3322 break; 3323 case 'X': 3324 /* XX/XY -- 2/4 way fork. */ 3325 for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1)) 3326 expand_opcode ((val << 2) | j, i, s + 2); 3327 break; 3328 case 'a': 3329 /* aa/ax -- 2/4 way fork. */ 3330 for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1)) 3331 expand_opcode ((val << 2) | j, i, s + 2); 3332 break; 3333 case 'Y': 3334 /* YY/YX -- 2/4 way fork. */ 3335 for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1) 3336 expand_opcode ((val << 2) | j, i, s + 2); 3337 break; 3338 case 'A': 3339 /* AA/AY: 2/4 way fork. */ 3340 for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1) 3341 expand_opcode ((val << 2) | j, i, s + 2); 3342 break; 3343 case 'v': 3344 /* vv(VV) -- 4(16) way fork. */ 3345 /* Vector register fv0/4/8/12. */ 3346 if (s[2] == 'V') 3347 { 3348 /* 2 vector registers. */ 3349 for (j = 0; j < 15; j++) 3350 expand_opcode ((val << 4) | j, i, s + 4); 3351 } 3352 else 3353 { 3354 /* 1 vector register. */ 3355 for (j = 0; j < 4; j += 1) 3356 expand_opcode ((val << 2) | j, i, s + 2); 3357 } 3358 break; 3359 } 3360 } 3361 } 3362 3363 /* Print the jump table used to index an opcode into a switch 3364 statement entry. */ 3365 3366 static void 3367 dumptable (const char *name, int size, int start) 3368 { 3369 int lump = 256; 3370 int online = 16; 3371 3372 int i = start; 3373 3374 printf ("unsigned short %s[%d] = {\n", name, size); 3375 while (i < start + size) 3376 { 3377 int j = 0; 3378 3379 printf ("/* 0x%x */\n", i); 3380 3381 while (j < lump) 3382 { 3383 int k = 0; 3384 while (k < online) 3385 { 3386 printf ("%2d", table[i + j + k]); 3387 if (j + k < lump) 3388 printf (","); 3389 3390 k++; 3391 } 3392 j += k; 3393 printf ("\n"); 3394 } 3395 i += j; 3396 } 3397 printf ("};\n"); 3398 } 3399 3400 3401 static void 3402 filltable (op *p) 3403 { 3404 static int index = 1; 3405 3406 sorttab (); 3407 for (; p->name; p++) 3408 { 3409 p->index = index++; 3410 expand_opcode (0, p->index, p->code); 3411 } 3412 } 3413 3414 /* Table already contains all the switch case tags for 16-bit opcode double 3415 data transfer (ddt) insns, and the switch case tag for processing parallel 3416 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the 3417 latter tag to represent all combinations of ppi with ddt. */ 3418 static void 3419 expand_ppi_movxy (void) 3420 { 3421 int i; 3422 3423 for (i = 0xf000; i < 0xf400; i++) 3424 if (table[i]) 3425 table[i + 0x800] = table[0xf800]; 3426 } 3427 3428 static void 3429 gensim_caselist (op *p) 3430 { 3431 for (; p->name; p++) 3432 { 3433 int j; 3434 int sextbit = -1; 3435 int needm = 0; 3436 int needn = 0; 3437 const char *s = p->code; 3438 3439 printf (" /* %s %s */\n", p->name, p->code); 3440 printf (" case %d:\n", p->index); 3441 3442 printf (" {\n"); 3443 while (*s) 3444 { 3445 switch (*s) 3446 { 3447 default: 3448 fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n", 3449 *s); 3450 exit (1); 3451 break; 3452 case '?': 3453 /* Wildcard expansion, nothing to do here. */ 3454 s += 2; 3455 break; 3456 case 'v': 3457 printf (" int v1 = ((iword >> 10) & 3) * 4;\n"); 3458 s += 2; 3459 break; 3460 case 'V': 3461 printf (" int v2 = ((iword >> 8) & 3) * 4;\n"); 3462 s += 2; 3463 break; 3464 case '0': 3465 case '1': 3466 s += 2; 3467 break; 3468 case '.': 3469 s += 4; 3470 break; 3471 case 'n': 3472 case 'e': 3473 printf (" int n = (iword >> 8) & 0xf;\n"); 3474 needn = 1; 3475 s += 4; 3476 break; 3477 case 'N': 3478 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n"); 3479 s += 2; 3480 break; 3481 case 'x': 3482 if (s[1] == 'y') /* xy */ 3483 { 3484 printf (" int n = (iword & 3) ?\n"); 3485 printf (" ((iword >> 9) & 1) + 4 :\n"); 3486 printf (" REG_xy ((iword >> 8) & 3);\n"); 3487 } 3488 else 3489 printf (" int n = ((iword >> 9) & 1) + 4;\n"); 3490 needn = 1; 3491 s += 2; 3492 break; 3493 case 'y': 3494 if (s[1] == 'x') /* yx */ 3495 { 3496 printf (" int n = (iword & 0xc) ?\n"); 3497 printf (" ((iword >> 8) & 1) + 6 :\n"); 3498 printf (" REG_yx ((iword >> 8) & 3);\n"); 3499 } 3500 else 3501 printf (" int n = ((iword >> 8) & 1) + 6;\n"); 3502 needn = 1; 3503 s += 2; 3504 break; 3505 case 'm': 3506 needm = 1; 3507 case 's': 3508 case 'M': 3509 case 'G': 3510 printf (" int m = (iword >> 4) & 0xf;\n"); 3511 s += 4; 3512 break; 3513 case 'X': 3514 if (s[1] == 'Y') /* XY */ 3515 { 3516 printf (" int m = (iword & 3) ?\n"); 3517 printf (" ((iword >> 7) & 1) + 8 :\n"); 3518 printf (" DSP_xy ((iword >> 6) & 3);\n"); 3519 } 3520 else 3521 printf (" int m = ((iword >> 7) & 1) + 8;\n"); 3522 s += 2; 3523 break; 3524 case 'a': 3525 if (s[1] == 'x') /* ax */ 3526 { 3527 printf (" int m = (iword & 3) ?\n"); 3528 printf (" 7 - ((iword >> 6) & 2) :\n"); 3529 printf (" DSP_ax ((iword >> 6) & 3);\n"); 3530 } 3531 else 3532 printf (" int m = 7 - ((iword >> 6) & 2);\n"); 3533 s += 2; 3534 break; 3535 case 'Y': 3536 if (s[1] == 'X') /* YX */ 3537 { 3538 printf (" int m = (iword & 0xc) ?\n"); 3539 printf (" ((iword >> 6) & 1) + 10 :\n"); 3540 printf (" DSP_yx ((iword >> 6) & 3);\n"); 3541 } 3542 else 3543 printf (" int m = ((iword >> 6) & 1) + 10;\n"); 3544 s += 2; 3545 break; 3546 case 'A': 3547 if (s[1] == 'Y') /* AY */ 3548 { 3549 printf (" int m = (iword & 0xc) ?\n"); 3550 printf (" 7 - ((iword >> 5) & 2) :\n"); 3551 printf (" DSP_ay ((iword >> 6) & 3);\n"); 3552 } 3553 else 3554 printf (" int m = 7 - ((iword >> 5) & 2);\n"); 3555 s += 2; 3556 break; 3557 3558 case 'i': 3559 printf (" int i = (iword & 0x"); 3560 3561 switch (s[1]) 3562 { 3563 default: 3564 fprintf (stderr, 3565 "gensim_caselist: Unknown char '%c' in %s\n", 3566 s[1], s); 3567 exit (1); 3568 break; 3569 case '4': 3570 printf ("f"); 3571 break; 3572 case '8': 3573 printf ("ff"); 3574 break; 3575 case '1': 3576 sextbit = 12; 3577 printf ("fff"); 3578 break; 3579 } 3580 printf (")"); 3581 3582 switch (s[3]) 3583 { 3584 default: 3585 fprintf (stderr, 3586 "gensim_caselist: Unknown char '%c' in %s\n", 3587 s[3], s); 3588 exit (1); 3589 break; 3590 case '.': /* eg. "i12." */ 3591 break; 3592 case '1': 3593 break; 3594 case '2': 3595 printf (" << 1"); 3596 break; 3597 case '4': 3598 printf (" << 2"); 3599 break; 3600 } 3601 printf (";\n"); 3602 s += 4; 3603 } 3604 } 3605 if (sextbit > 0) 3606 { 3607 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n", 3608 sextbit - 1, sextbit - 1); 3609 } 3610 3611 if (needm && needn) 3612 printf (" TB (m,n);\n"); 3613 else if (needm) 3614 printf (" TL (m);\n"); 3615 else if (needn) 3616 printf (" TL (n);\n"); 3617 3618 { 3619 /* Do the refs. */ 3620 const char *r; 3621 for (r = p->refs; *r; r++) 3622 { 3623 if (*r == 'f') printf (" CREF (15);\n"); 3624 if (*r == '-') 3625 { 3626 printf (" {\n"); 3627 printf (" int i = n;\n"); 3628 printf (" do {\n"); 3629 printf (" CREF (i);\n"); 3630 printf (" } while (i-- > 0);\n"); 3631 printf (" }\n"); 3632 } 3633 if (*r == '+') 3634 { 3635 printf (" {\n"); 3636 printf (" int i = n;\n"); 3637 printf (" do {\n"); 3638 printf (" CREF (i);\n"); 3639 printf (" } while (i++ < 14);\n"); 3640 printf (" }\n"); 3641 } 3642 if (*r == '0') printf (" CREF (0);\n"); 3643 if (*r == '8') printf (" CREF (8);\n"); 3644 if (*r == '9') printf (" CREF (9);\n"); 3645 if (*r == 'n') printf (" CREF (n);\n"); 3646 if (*r == 'm') printf (" CREF (m);\n"); 3647 } 3648 } 3649 3650 printf (" {\n"); 3651 for (j = 0; j < MAX_NR_STUFF; j++) 3652 { 3653 if (p->stuff[j]) 3654 { 3655 printf (" %s\n", p->stuff[j]); 3656 } 3657 } 3658 printf (" }\n"); 3659 3660 { 3661 /* Do the defs. */ 3662 const char *r; 3663 for (r = p->defs; *r; r++) 3664 { 3665 if (*r == 'f') printf (" CDEF (15);\n"); 3666 if (*r == '-') 3667 { 3668 printf (" {\n"); 3669 printf (" int i = n;\n"); 3670 printf (" do {\n"); 3671 printf (" CDEF (i);\n"); 3672 printf (" } while (i-- > 0);\n"); 3673 printf (" }\n"); 3674 } 3675 if (*r == '+') 3676 { 3677 printf (" {\n"); 3678 printf (" int i = n;\n"); 3679 printf (" do {\n"); 3680 printf (" CDEF (i);\n"); 3681 printf (" } while (i++ < 14);\n"); 3682 printf (" }\n"); 3683 } 3684 if (*r == '0') printf (" CDEF (0);\n"); 3685 if (*r == 'n') printf (" CDEF (n);\n"); 3686 if (*r == 'm') printf (" CDEF (m);\n"); 3687 } 3688 } 3689 3690 printf (" break;\n"); 3691 printf (" }\n"); 3692 } 3693 } 3694 3695 static void 3696 gensim (void) 3697 { 3698 printf ("{\n"); 3699 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n"); 3700 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n"); 3701 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n"); 3702 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n"); 3703 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n"); 3704 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n"); 3705 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n"); 3706 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n"); 3707 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n"); 3708 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n"); 3709 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n"); 3710 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n"); 3711 printf (" switch (jump_table[iword]) {\n"); 3712 3713 gensim_caselist (tab); 3714 gensim_caselist (movsxy_tab); 3715 3716 printf (" default:\n"); 3717 printf (" {\n"); 3718 printf (" RAISE_EXCEPTION (SIGILL);\n"); 3719 printf (" }\n"); 3720 printf (" }\n"); 3721 printf ("}\n"); 3722 } 3723 3724 static void 3725 gendefines (void) 3726 { 3727 op *p; 3728 filltable (tab); 3729 for (p = tab; p->name; p++) 3730 { 3731 const char *s = p->name; 3732 printf ("#define OPC_"); 3733 while (*s) { 3734 if (isalpha (*s)) 3735 printf ("%c", tolower (*s)); 3736 if (*s == ' ') 3737 printf ("_"); 3738 if (*s == '@') 3739 printf ("ind_"); 3740 if (*s == ',') 3741 printf ("_"); 3742 s++; 3743 } 3744 printf (" %d\n",p->index); 3745 } 3746 } 3747 3748 static int ppi_index; 3749 3750 /* Take a ppi code, expand all varying fields in it and fill all the 3751 right entries in 'table' with the opcode index. 3752 NOTE: tail recursion optimization removed for simplicity. */ 3753 3754 static void 3755 expand_ppi_code (int val, int i, const char *s) 3756 { 3757 int j; 3758 3759 switch (s[0]) 3760 { 3761 default: 3762 fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]); 3763 exit (2); 3764 break; 3765 case 'g': 3766 case 'z': 3767 if (warn_conflicts && table[val] != 0) 3768 conflict_warn (val, i); 3769 3770 /* The last four bits are disregarded for the switch table. */ 3771 table[val] = i; 3772 return; 3773 case 'm': 3774 /* Four-bit expansion. */ 3775 for (j = 0; j < 16; j++) 3776 expand_ppi_code ((val << 4) + j, i, s + 4); 3777 break; 3778 case '.': 3779 case '0': 3780 expand_ppi_code ((val << 1), i, s + 1); 3781 break; 3782 case '1': 3783 expand_ppi_code ((val << 1) + 1, i, s + 1); 3784 break; 3785 case 'i': 3786 case 'e': case 'f': 3787 case 'x': case 'y': 3788 expand_ppi_code ((val << 1), i, s + 1); 3789 expand_ppi_code ((val << 1) + 1, i, s + 1); 3790 break; 3791 case 'c': 3792 expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2); 3793 expand_ppi_code ((val << 2) + 2, i, s + 2); 3794 expand_ppi_code ((val << 2) + 3, i, s + 2); 3795 break; 3796 } 3797 } 3798 3799 static void 3800 ppi_filltable (void) 3801 { 3802 op *p; 3803 ppi_index = 1; 3804 3805 for (p = ppi_tab; p->name; p++) 3806 { 3807 p->index = ppi_index++; 3808 expand_ppi_code (0, p->index, p->code); 3809 } 3810 } 3811 3812 static void 3813 ppi_gensim (void) 3814 { 3815 op *p = ppi_tab; 3816 3817 printf ("#define DSR_MASK_G 0x80\n"); 3818 printf ("#define DSR_MASK_Z 0x40\n"); 3819 printf ("#define DSR_MASK_N 0x20\n"); 3820 printf ("#define DSR_MASK_V 0x10\n"); 3821 printf ("\n"); 3822 printf ("#define COMPUTE_OVERFLOW do {\\\n"); 3823 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;\\\n"); 3824 printf (" if (overflow && S) \\\n"); 3825 printf (" { \\\n"); 3826 printf (" if (res_grd & 0x80) \\\n"); 3827 printf (" { \\\n"); 3828 printf (" res = 0x80000000;\\\n"); 3829 printf (" res_grd |= 0xff;\\\n"); 3830 printf (" } \\\n"); 3831 printf (" else \\\n"); 3832 printf (" { \\\n"); 3833 printf (" res = 0x7fffffff;\\\n"); 3834 printf (" res_grd &= ~0xff;\\\n"); 3835 printf (" } \\\n"); 3836 printf (" overflow = 0;\\\n"); 3837 printf (" } \\\n"); 3838 printf ("} while (0)\n"); 3839 printf ("\n"); 3840 printf ("#define ADD_SUB_GE \\\n"); 3841 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n"); 3842 printf ("\n"); 3843 printf ("static void\n"); 3844 printf ("ppi_insn (int iword)\n"); 3845 printf ("{\n"); 3846 printf (" /* 'ee' = [x0, x1, y0, a1] */\n"); 3847 printf (" static char const e_tab[] = { 8, 9, 10, 5};\n"); 3848 printf (" /* 'ff' = [y0, y1, x0, a1] */\n"); 3849 printf (" static char const f_tab[] = {10, 11, 8, 5};\n"); 3850 printf (" /* 'xx' = [x0, x1, a0, a1] */\n"); 3851 printf (" static char const x_tab[] = { 8, 9, 7, 5};\n"); 3852 printf (" /* 'yy' = [y0, y1, m0, m1] */\n"); 3853 printf (" static char const y_tab[] = {10, 11, 12, 14};\n"); 3854 printf (" /* 'gg' = [m0, m1, a0, a1] */\n"); 3855 printf (" static char const g_tab[] = {12, 14, 7, 5};\n"); 3856 printf (" /* 'uu' = [x0, y0, a0, a1] */\n"); 3857 printf (" static char const u_tab[] = { 8, 10, 7, 5};\n"); 3858 printf ("\n"); 3859 printf (" int z;\n"); 3860 printf (" int res, res_grd;\n"); 3861 printf (" int carry, overflow, greater_equal;\n"); 3862 printf ("\n"); 3863 printf (" switch (ppi_table[iword >> 4]) {\n"); 3864 3865 for (; p->name; p++) 3866 { 3867 int shift, j; 3868 int cond = 0; 3869 int havedecl = 0; 3870 const char *s = p->code; 3871 3872 printf (" /* %s %s */\n", p->name, p->code); 3873 printf (" case %d:\n", p->index); 3874 3875 printf (" {\n"); 3876 for (shift = 16; *s; ) 3877 { 3878 switch (*s) 3879 { 3880 case 'i': 3881 printf (" int i = (iword >> 4) & 0x7f;\n"); 3882 s += 6; 3883 break; 3884 case 'e': 3885 case 'f': 3886 case 'x': 3887 case 'y': 3888 case 'g': 3889 case 'u': 3890 shift -= 2; 3891 printf (" int %c = %c_tab[(iword >> %d) & 3];\n", 3892 *s, *s, shift); 3893 havedecl = 1; 3894 s += 2; 3895 break; 3896 case 'c': 3897 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n"); 3898 printf ("\treturn;\n"); 3899 printf (" ATTRIBUTE_FALLTHROUGH;\n"); 3900 printf (" }\n"); 3901 printf (" case %d:\n", p->index + 1); 3902 printf (" {\n"); 3903 cond = 1; 3904 case '0': 3905 case '1': 3906 case '.': 3907 shift -= 2; 3908 s += 2; 3909 break; 3910 case 'z': 3911 if (havedecl) 3912 printf ("\n"); 3913 printf (" z = iword & 0xf;\n"); 3914 havedecl = 2; 3915 s += 4; 3916 break; 3917 } 3918 } 3919 if (havedecl == 1) 3920 printf ("\n"); 3921 else if (havedecl == 2) 3922 printf (" {\n"); 3923 for (j = 0; j < MAX_NR_STUFF; j++) 3924 { 3925 if (p->stuff[j]) 3926 { 3927 if (*p->stuff[j]) 3928 { 3929 printf (" %s%s", 3930 (havedecl == 2 ? " " : ""), 3931 p->stuff[j]); 3932 } 3933 printf ("\n"); 3934 } 3935 } 3936 if (havedecl == 2) 3937 printf (" }\n"); 3938 if (cond) 3939 { 3940 printf (" if (iword & 0x200)\n"); 3941 printf (" goto assign_z;\n"); 3942 } 3943 printf (" break;\n"); 3944 printf (" }\n"); 3945 } 3946 3947 printf (" default:\n"); 3948 printf (" {\n"); 3949 printf (" RAISE_EXCEPTION (SIGILL);\n"); 3950 printf (" return;\n"); 3951 printf (" }\n"); 3952 printf (" }\n"); 3953 printf (" DSR &= ~0xf1;\n"); 3954 printf (" if (res || res_grd)\n"); 3955 printf (" DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n"); 3956 printf (" else\n"); 3957 printf (" DSR |= DSR_MASK_Z | overflow;\n"); 3958 printf (" assign_dc:\n"); 3959 printf (" switch (DSR >> 1 & 7)\n"); 3960 printf (" {\n"); 3961 printf (" case 0: /* Carry Mode */\n"); 3962 printf (" DSR |= carry;\n"); 3963 printf (" break;\n"); 3964 printf (" case 1: /* Negative Value Mode */\n"); 3965 printf (" DSR |= res_grd >> 7 & 1;\n"); 3966 printf (" break;\n"); 3967 printf (" case 2: /* Zero Value Mode */\n"); 3968 printf (" DSR |= DSR >> 6 & 1;\n"); 3969 printf (" break;\n"); 3970 printf (" case 3: /* Overflow mode */\n"); 3971 printf (" DSR |= overflow >> 4;\n"); 3972 printf (" break;\n"); 3973 printf (" case 4: /* Signed Greater Than Mode */\n"); 3974 printf (" DSR |= DSR >> 7 & 1;\n"); 3975 printf (" break;\n"); 3976 printf (" case 5: /* Signed Greater Than Or Equal Mode */\n"); 3977 printf (" DSR |= greater_equal >> 7;\n"); 3978 printf (" break;\n"); 3979 printf (" }\n"); 3980 printf (" assign_z:\n"); 3981 printf (" if (0xa05f >> z & 1)\n"); 3982 printf (" {\n"); 3983 printf (" RAISE_EXCEPTION (SIGILL);\n"); 3984 printf (" return;\n"); 3985 printf (" }\n"); 3986 printf (" DSP_R (z) = res;\n"); 3987 printf (" DSP_GRD (z) = res_grd;\n"); 3988 printf ("}\n"); 3989 } 3990 3991 int 3992 main (int ac, char *av[]) 3993 { 3994 /* Verify the table before anything else. */ 3995 { 3996 op *p; 3997 for (p = tab; p->name; p++) 3998 { 3999 /* Check that the code field contains 16 bits. */ 4000 if (strlen (p->code) != 16) 4001 { 4002 fprintf (stderr, "Code `%s' length wrong (%zu) for `%s'\n", 4003 p->code, strlen (p->code), p->name); 4004 abort (); 4005 } 4006 } 4007 } 4008 4009 /* Now generate the requested data. */ 4010 if (ac > 1) 4011 { 4012 if (ac > 2 && strcmp (av[2], "-w") == 0) 4013 { 4014 warn_conflicts = 1; 4015 } 4016 if (strcmp (av[1], "-t") == 0) 4017 { 4018 gengastab (); 4019 } 4020 else if (strcmp (av[1], "-d") == 0) 4021 { 4022 gendefines (); 4023 } 4024 else if (strcmp (av[1], "-s") == 0) 4025 { 4026 filltable (tab); 4027 dumptable ("sh_jump_table", 1 << 16, 0); 4028 4029 memset (table, 0, sizeof table); 4030 filltable (movsxy_tab); 4031 expand_ppi_movxy (); 4032 dumptable ("sh_dsp_table", 1 << 12, 0xf000); 4033 4034 memset (table, 0, sizeof table); 4035 ppi_filltable (); 4036 dumptable ("ppi_table", 1 << 12, 0); 4037 } 4038 else if (strcmp (av[1], "-x") == 0) 4039 { 4040 filltable (tab); 4041 filltable (movsxy_tab); 4042 gensim (); 4043 } 4044 else if (strcmp (av[1], "-p") == 0) 4045 { 4046 ppi_filltable (); 4047 ppi_gensim (); 4048 } 4049 } 4050 else 4051 fprintf (stderr, "Opcode table generation no longer supported.\n"); 4052 return 0; 4053 } 4054