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