1 /* Simulator/Opcode generator for the Renesas
2 (formerly Hitachi) / SuperH Inc. Super-H architecture.
4 Written by Steve Chamberlain of Cygnus Support.
7 This file is part of SH sim.
10 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
22 /* This program generates the opcode table for the assembler and
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
38 #include "libiberty.h"
40 #define MAX_NR_STUFF 42
48 const char * const stuff
[MAX_NR_STUFF
];
56 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
59 " UNDEF(n); /* see #ifdef PARANOID */",
63 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
67 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
69 "SET_SR_T (ult < R[n]);",
71 "SET_SR_T (T || (R[n] < ult));",
74 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
76 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
80 { "0", "0", "and #<imm>,R0", "11001001i8*1....",
83 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
86 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
88 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
91 { "", "", "bf <bdisp8>", "10001011i8p1....",
92 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
94 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
99 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
100 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
102 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
104 " Delay_Slot (PC + 2);",
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. */",
115 " RAISE_EXCEPTION (SIGILL);",
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. */",
121 { "", "", "bra <bdisp12>", "1010i12.........",
122 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
123 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
125 "Delay_Slot (PC + 2);",
128 { "", "n", "braf <REG_N>", "0000nnnn00100011",
129 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
130 "SET_NIP (PC + 4 + R[n]);",
132 "Delay_Slot (PC + 2);",
135 { "", "", "bsr <bdisp12>", "1011i12.........",
136 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
137 "PR = PH2T (PC + 4);",
138 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
140 "Delay_Slot (PC + 2);",
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]);",
148 "Delay_Slot (PC + 2);",
151 { "", "", "bt <bdisp8>", "10001001i8p1....",
152 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
154 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
159 { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
160 "/* MSB of 'i' is true for load, false for store. */",
163 " R[m] |= (1 << i);",
165 " R[m] &= ~(1 << i);",
167 " SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
169 { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
170 "/* MSB of 'i' is true for set, false for clear. */",
172 " R[m] &= ~(1 << i);",
174 " R[m] |= (1 << (i - 8));",
176 { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
177 "if (R[n] < -128 || R[n] > 127) {",
182 " else if (R[n] < -128)",
186 { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
187 "if (R[n] < -32768 || R[n] > 32767) {",
190 " if (R[n] > 32767)",
192 " else if (R[n] < -32768)",
196 { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
197 "if (R[n] < -256 || R[n] > 255) {",
203 { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
204 "if (R[n] < -65536 || R[n] > 65535) {",
210 { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
211 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
213 " R[n] = 0x7fffffff;",
214 "else if (R0 == -1 && R[n] == 0x80000000)",
215 " R[n] = 0x7fffffff;",
219 { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
220 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
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;",
228 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
229 "R[n] = (R[n] * R0) & 0xffffffff;",
232 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
233 "int regn = (R[n] >> 2) & 0x1f;",
234 "int bankn = (R[n] >> 7) & 0x1ff;",
236 " regn = 19; /* FIXME what should happen? */",
237 "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
240 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
241 "int regn = (R[n] >> 2) & 0x1f;",
242 "int bankn = (R[n] >> 7) & 0x1ff;",
244 " regn = 19; /* FIXME what should happen? */",
245 "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
247 { "", "", "resbank", "0000000001011011",
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]);",
258 " PR = RLAT (R[15]);",
261 " GBR = RLAT (R[15]);",
264 " MACH = RLAT (R[15]);",
267 " MACL = RLAT (R[15]);",
271 "else if (BANKN == 0) /* Bank Underflow */",
272 " RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */
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];",
283 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
284 "/* Push Rn...R0 (if n==15, push pr and R14...R0). */",
289 " WLAT (R[15], PR);",
291 " WLAT (R[15], R[n]);",
292 "} while (n-- > 0);",
294 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
295 "/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */",
300 " PR = RLAT (R[15]);",
302 " R[i] = RLAT (R[15]);",
304 "} while (i++ < n);",
306 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
307 "/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */
313 " WLAT (R[15], PR);",
315 " WLAT (R[15], R[i]);",
316 "} while (i-- > n);",
318 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
319 "/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */
323 " PR = RLAT (R[15]);",
325 " R[n] = RLAT (R[15]);",
327 "} while (n++ < 15);",
329 { "", "", "nott", "0000000001101000",
330 "SET_SR_T (T == 0);",
333 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
334 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
336 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
338 " Delay_Slot (PC + 2);",
342 { "", "", "clrmac", "0000000000101000",
347 { "", "", "clrs", "0000000001001000",
351 { "", "", "clrt", "0000000000001000",
356 { "", "", "clrdmxy", "0000000010001000",
357 "saved_state.asregs.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
360 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
361 "SET_SR_T (R0 == SEXT (i));",
363 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
364 "SET_SR_T (R[n] == R[m]);",
366 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
367 "SET_SR_T (R[n] >= R[m]);",
369 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
370 "SET_SR_T (R[n] > R[m]);",
372 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
373 "SET_SR_T (UR[n] > UR[m]);",
375 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
376 "SET_SR_T (UR[n] >= UR[m]);",
378 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
379 "SET_SR_T (R[n] > 0);",
381 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
382 "SET_SR_T (R[n] >= 0);",
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));",
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);",
398 { "", "", "div0u", "0000000000011001",
404 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
405 "div1 (&R0, m, n/*, T*/);",
408 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
409 "dmul_s (R[n], R[m]);",
412 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
413 "dmul_u (R[n], R[m]);",
416 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
418 "SET_SR_T (R[n] == 0);",
421 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
422 "R[n] = SEXT (R[m]);",
424 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
425 "R[n] = SEXTW (R[m]);",
428 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
429 "R[n] = (R[m] & 0xff);",
431 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
432 "R[n] = (R[m] & 0xffff);",
436 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
443 " u.i &= 0x7fffffff;",
448 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
453 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
454 "FP_CMP (n, ==, m);",
457 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
462 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
463 "if (! FPSCR_PR || n & 1)",
464 " RAISE_EXCEPTION (SIGILL);",
478 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
479 "if (! FPSCR_PR || n & 1)",
480 " RAISE_EXCEPTION (SIGILL);",
494 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
496 "/* FIXME: check for DP and (n & 1) == 0? */",
500 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
502 " RAISE_EXCEPTION (SIGILL);",
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);",
518 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
519 "SET_FR (n, (float) 0.0);",
520 "/* FIXME: check for DP and (n & 1) == 0? */",
524 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
525 "SET_FR (n, (float) 1.0);",
526 "/* FIXME: check for DP and (n & 1) == 0? */",
530 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
541 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
544 " SET_DR (n, (double) FPUL);",
547 " SET_FR (n, (float) FPUL);",
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? */",
558 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
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));",
568 " SET_FR (n, FR (m));",
572 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
581 " WLAT (R[n], FI (m));",
585 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
594 " SET_FI (n, RLAT (R[m]));",
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. */",
607 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
610 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
620 " SET_FI (n, RLAT (R[m]));",
625 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
636 " WLAT (R[n], FI (m));",
640 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
644 " RDAT (R[0]+R[m], n);",
649 " SET_FI (n, RLAT (R[0] + R[m]));",
653 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
657 " WDAT (R[0]+R[n], m);",
662 " WLAT ((R[0]+R[n]), FI (m));",
667 See fmov instructions above for move to/from extended fp registers. */
670 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
675 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
682 " u.i ^= 0x80000000;",
687 { "", "", "fpchg", "1111011111111101",
688 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
692 { "", "", "frchg", "1111101111111101",
694 " RAISE_EXCEPTION (SIGILL);",
695 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
696 " RAISE_EXCEPTION (SIGILL);",
698 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
702 { "", "", "fsca", "1111eeee11111101",
704 " RAISE_EXCEPTION (SIGILL);",
705 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
706 " RAISE_EXCEPTION (SIGILL);",
709 " SET_FR (n, fsca_s (FPUL, &sin));",
710 " SET_FR (n+1, fsca_s (FPUL, &cos));",
715 { "", "", "fschg", "1111001111111101",
716 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
720 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
721 "FP_UNARY (n, sqrt);",
725 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
727 " RAISE_EXCEPTION (SIGILL);",
728 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
729 " RAISE_EXCEPTION (SIGILL);",
731 " SET_FR (n, fsrra_s (FR (n)));",
735 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
740 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
743 " if (DR (n) != DR (n)) /* NaN */",
744 " FPUL = 0x80000000;",
746 " FPUL = (int) DR (n);",
749 "if (FR (n) != FR (n)) /* NaN */",
750 " FPUL = 0x80000000;",
752 " FPUL = (int) FR (n);",
756 { "", "", "ftrv <FV_N>", "1111vv0111111101",
758 " RAISE_EXCEPTION (SIGILL);",
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);",
769 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
779 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
780 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
781 "SET_NIP (PT2H (R[n]));",
783 "Delay_Slot (PC + 2);",
786 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
787 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
788 "PR = PH2T (PC + 4);",
790 " gotcall (PR, R[n]);",
791 "SET_NIP (PT2H (R[n]));",
793 "Delay_Slot (PC + 2);",
795 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
796 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
797 "PR = PH2T (PC + 2);",
799 " gotcall (PR, R[n]);",
800 "SET_NIP (PT2H (R[n]));",
802 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
803 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
804 "PR = PH2T (PC + 2);",
806 " gotcall (PR, i + TBR);",
807 "SET_NIP (PT2H (i + TBR));",
810 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
812 "/* FIXME: user mode */",
814 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
816 "/* FIXME: user mode */",
818 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
821 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
823 " DBR = R[n]; /* priv mode */",
825 " RAISE_EXCEPTION (SIGILL); /* user mode */",
827 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
829 " SGR = R[n]; /* priv mode */",
831 " RAISE_EXCEPTION (SIGILL); /* user mode */",
833 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
834 "if (SR_MD)", /* FIXME? */
835 " TBR = R[n]; /* priv mode */",
837 " RAISE_EXCEPTION (SIGILL); /* user mode */",
839 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
841 "CREG (m) = RLAT (R[n]);",
843 "/* FIXME: user mode */",
845 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
847 "SET_SR (RLAT (R[n]));",
849 "/* FIXME: user mode */",
851 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
853 "SET_MOD (RLAT (R[n]));",
856 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
860 " DBR = RLAT (R[n]);",
864 " RAISE_EXCEPTION (SIGILL); /* user mode */",
866 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
870 " SGR = RLAT (R[n]);",
874 " RAISE_EXCEPTION (SIGILL); /* user mode */",
878 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
879 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
881 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
882 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
886 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
888 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
889 "CHECK_INSN_PTR (insn_ptr);",
892 { "", "", "ldrc #<imm>", "10001010i8*1....",
894 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
895 "CHECK_INSN_PTR (insn_ptr);",
899 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
902 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
904 "SREG (m) = RLAT (R[n]);",
907 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
908 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
911 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
912 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
914 "SET_FPSCR (RLAT (R[n]));",
918 { "", "", "ldtlb", "0000000000111000",
919 "/* We don't implement cache or tlb, so this is a noop. */",
922 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
923 "macl (&R0, memory, n, m);",
926 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
927 "macw (&R0, memory, n, m, endianw);",
930 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
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. */",
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. */",
943 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
947 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
949 "R0 = RSBAT (i + GBR);",
952 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
954 "R0 = RSBAT (i + R[m]);",
957 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
959 "R[n] = RSBAT (R0 + R[m]);",
962 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
964 "R[n] = RSBAT (R[m]);",
968 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
971 "R0 = RSBAT (R[n]);",
974 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
976 "WBAT (R[n], R[m]);",
978 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
980 "WBAT (i + GBR, R0);",
982 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
984 "WBAT (i + R[m], R0);",
986 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
988 "WBAT (R[n] + R0, R[m]);",
990 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
991 /* Allow for the case where m == n. */
997 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
1002 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
1004 "R[n] = RSBAT (R[m]);",
1008 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
1010 "R0 = RLAT (i + GBR);",
1013 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
1014 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1016 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
1019 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1021 "R[n] = RLAT (i + R[m]);",
1024 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1026 "R[n] = RLAT (R0 + R[m]);",
1029 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1031 "R[n] = RLAT (R[m]);",
1035 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1038 "R0 = RLAT (R[n]);",
1041 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1043 "R[n] = RLAT (R[m]);",
1046 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1048 "WLAT (i + GBR, R0);",
1050 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1052 "WLAT (i + R[n], R[m]);",
1054 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1056 "WLAT (R0 + R[n], R[m]);",
1058 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1059 /* Allow for the case where m == n. */
1065 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1070 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1072 "WLAT (R[n], R[m]);",
1075 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1077 "R0 = RSWAT (i + GBR);",
1080 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1081 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1083 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1086 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1088 "R0 = RSWAT (i + R[m]);",
1091 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1093 "R[n] = RSWAT (R0 + R[m]);",
1096 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1098 "R[n] = RSWAT (R[m]);",
1102 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1105 "R0 = RSWAT (R[n]);",
1108 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1110 "R[n] = RSWAT (R[m]);",
1113 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1115 "WWAT (i + GBR, R0);",
1117 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1119 "WWAT (i + R[m], R0);",
1121 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1123 "WWAT (R0 + R[n], R[m]);",
1125 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1126 /* Allow for the case where m == n. */
1132 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1137 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1139 "WWAT (R[n], R[m]);",
1142 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1143 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1144 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1147 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1148 "/* We don't simulate cache, so this insn is identical to mov. */",
1150 "WLAT (R[n], R[0]);",
1153 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1156 "/* if (T) R0 -> (Rn) */",
1158 " WLAT (R[n], R[0]);",
1163 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1167 "R[0] = RLAT (R[n]);",
1168 "/* if (interrupt/exception) 0 -> LDST */",
1169 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1172 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1175 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1178 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1180 "int e = target_little_endian ? 3 : 0;",
1182 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1183 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1186 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1188 "int e = target_little_endian ? 3 : 0;",
1190 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1191 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1195 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1196 "MACL = ((int) R[n]) * ((int) R[m]);",
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];",
1205 /* muls.w - see muls */
1206 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1207 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
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]));",
1216 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1220 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1222 "SET_SR_T (ult > 0);",
1223 "R[n] = ult - R[m];",
1224 "SET_SR_T (T || (R[n] > ult));",
1227 { "", "", "nop", "0000000000001001",
1231 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1236 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1237 "/* Except for the effect on the cache - which is not simulated -",
1238 " this is like a nop. */",
1241 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1242 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1243 "/* FIXME: Cache not implemented */",
1246 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1247 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1248 "/* FIXME: Cache not implemented */",
1251 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1252 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1253 "/* FIXME: Cache not implemented */",
1256 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1259 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1262 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1264 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1267 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1268 "/* Except for the effect on the cache - which is not simulated -",
1269 " this is like a nop. */",
1273 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1274 "/* Except for the effect on the cache - which is not simulated -",
1275 " this is like a nop. */",
1279 { "", "", "synco", "0000000010101011",
1280 "/* Except for the effect on the pipeline - which is not simulated -",
1281 " this is like a nop. */",
1284 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1286 "R[n] = (R[n] << 1) | T;",
1290 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1292 "R[n] = (UR[n] >> 1) | (T << 31);",
1296 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1297 "SET_SR_T (R[n] < 0);",
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);",
1308 { "", "", "rte", "0000000000101011",
1312 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1314 "SET_SR (RLAT (R[15]) & 0x3f3);",
1316 "Delay_Slot (PC + 2);",
1318 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1320 "SET_NIP (PT2H (SPC));",
1322 "Delay_Slot (PC + 2);",
1326 { "", "", "rts", "0000000000001011",
1327 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1328 "SET_NIP (PT2H (PR));",
1330 "Delay_Slot (PC + 2);",
1332 { "", "", "rts/n", "0000000001101011",
1333 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1334 "SET_NIP (PT2H (PR));",
1336 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1337 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1340 "SET_NIP (PT2H (PR));",
1344 { "", "", "setdmx", "0000000010011000",
1345 "saved_state.asregs.sr |= SR_MASK_DMX;"
1346 "saved_state.asregs.sr &= ~SR_MASK_DMY;"
1350 { "", "", "setdmy", "0000000011001000",
1351 "saved_state.asregs.sr |= SR_MASK_DMY;"
1352 "saved_state.asregs.sr &= ~SR_MASK_DMX;"
1356 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
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);",
1368 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1369 " CHECK_INSN_PTR (insn_ptr);",
1373 { "", "", "sets", "0000000001011000",
1377 { "", "", "sett", "0000000000011000",
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));",
1385 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1386 "SET_SR_T (R[n] < 0);",
1390 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1391 "SET_SR_T (R[n] & 1);",
1392 "R[n] = R[n] >> 1;",
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));",
1399 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1400 "SET_SR_T (R[n] < 0);",
1404 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1407 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1410 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1414 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1415 "SET_SR_T (R[n] & 1);",
1416 "R[n] = UR[n] >> 1;",
1419 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1420 "R[n] = UR[n] >> 2;",
1422 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1423 "R[n] = UR[n] >> 8;",
1425 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1426 "R[n] = UR[n] >> 16;",
1429 { "", "", "sleep", "0000000000011011",
1430 "nip += trap (sd, 0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1433 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1437 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1439 " R[n] = SGR; /* priv mode */",
1441 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1443 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1445 " R[n] = DBR; /* priv mode */",
1447 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1449 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1450 "if (SR_MD)", /* FIXME? */
1451 " R[n] = TBR; /* priv mode */",
1453 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1455 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1458 "WLAT (R[n], CREG (m));",
1460 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1462 "{ /* priv mode */",
1465 " WLAT (R[n], SGR);",
1468 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1470 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1472 "{ /* priv mode */",
1475 " WLAT (R[n], DBR);",
1478 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1481 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1484 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1487 "WLAT (R[n], SREG (m));",
1490 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1494 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1496 "SET_SR_T (ult > R[n]);",
1497 "R[n] = ult - R[m];",
1498 "SET_SR_T (T || (R[n] > ult));",
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);",
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));",
1512 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1513 "R[n] = (((R[m] << 16) & 0xffff0000)",
1514 " | ((R[m] >> 16) & 0x00ffff));",
1517 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1519 "ult = RBAT (R[n]);",
1520 "SET_SR_T (ult == 0);",
1521 "WBAT (R[n],ult|0x80);",
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);",
1533 " WLAT (R[15], GET_SR ());",
1535 " WLAT (R[15], PH2T (PC + 2));",
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; */",
1543 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1547 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1548 "SET_SR_T ((R[n] & R[m]) == 0);",
1550 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1551 "SET_SR_T ((R0 & i) == 0);",
1553 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1555 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1558 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1561 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1564 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1566 "ult = RBAT (GBR+R0);",
1568 "WBAT (GBR + R0, ult);",
1571 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1572 "R[n] = (((R[n] >> 16) & 0xffff)",
1573 " | ((R[m] << 16) & 0xffff0000));",
1577 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1578 "divl (0, R[n], R[m]);",
1580 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1581 "divl (0, R[n], R[m]);",
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? */
1593 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1596 "DSP_R (m) = RSWAT (R[n]) << 16;",
1597 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1599 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1601 "DSP_R (m) = RSWAT (R[n]) << 16;",
1602 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1604 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1606 "DSP_R (m) = RSWAT (R[n]) << 16;",
1607 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1610 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1612 "DSP_R (m) = RSWAT (R[n]) << 16;",
1613 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1616 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1619 "DSP_R (m) = RSWAT (R[n]);",
1621 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1623 "DSP_R (m) = RSWAT (R[n]);",
1625 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1627 "DSP_R (m) = RSWAT (R[n]);",
1630 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1632 "DSP_R (m) = RSWAT (R[n]);",
1635 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1638 "WWAT (R[n], DSP_R (m) >> 16);",
1640 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1642 "WWAT (R[n], DSP_R (m) >> 16);",
1644 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1646 "WWAT (R[n], DSP_R (m) >> 16);",
1649 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1651 "WWAT (R[n], DSP_R (m) >> 16);",
1654 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1657 "WWAT (R[n], SEXT (DSP_R (m)));",
1659 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1661 "WWAT (R[n], SEXT (DSP_R (m)));",
1663 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1665 "WWAT (R[n], SEXT (DSP_R (m)));",
1668 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1670 "WWAT (R[n], SEXT (DSP_R (m)));",
1673 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1676 "DSP_R (m) = RLAT (R[n]);",
1677 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1679 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1681 "DSP_R (m) = RLAT (R[n]);",
1682 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1684 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1686 "DSP_R (m) = RLAT (R[n]);",
1687 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1690 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1692 "DSP_R (m) = RLAT (R[n]);",
1693 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1696 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1699 "WLAT (R[n], DSP_R (m));",
1701 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1703 "WLAT (R[n], DSP_R (m));",
1705 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1707 "WLAT (R[n], DSP_R (m));",
1710 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1712 "WLAT (R[n], DSP_R (m));",
1715 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1718 "WLAT (R[n], SEXT (DSP_R (m)));",
1720 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1722 "WLAT (R[n], SEXT (DSP_R (m)));",
1724 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1726 "WLAT (R[n], SEXT (DSP_R (m)));",
1729 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1731 "WLAT (R[n], SEXT (DSP_R (m)));",
1734 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1735 "DSP_R (m) = RSWAT (R[n]) << 16;",
1738 " iword &= 0xfd53; goto top;",
1741 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1742 "DSP_R (m) = RLAT (R[n]);",
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;",
1749 " iword &= 0xfd53; goto top;",
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;",
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];",
1761 " iword &= 0xfd53; goto top;",
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];",
1768 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1769 "WWAT (R[n], DSP_R (m) >> 16);",
1772 " iword &= 0xfd53; goto top;",
1775 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1776 "WLAT (R[n], DSP_R (m));",
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;",
1783 " iword &= 0xfd53; goto top;",
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;",
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];",
1795 " iword &= 0xfd53; goto top;",
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];",
1802 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1803 "DSP_R (m) = RSWAT (R[n]) << 16;",
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;",
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];",
1813 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1814 "WWAT (R[n], DSP_R (m) >> 16);",
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;",
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];",
1824 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1825 "DSP_R (m) = RLAT (R[n]);",
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;",
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];",
1835 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1836 "WLAT (R[n], DSP_R (m));",
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;",
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];",
1846 { "", "", "nopx nopy", "1111000000000000",
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;",
1860 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1861 "int Sz = DSP_R (z) & 0xffff0000;",
1865 "else if (i >= 128 - 16)",
1866 " res = (unsigned) Sz >> (128 - i); /* no sign extension */",
1869 " RAISE_EXCEPTION (SIGILL);",
1872 "res &= 0xffff0000;",
1876 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1877 "int Sz = DSP_R (z);",
1878 "int Sz_grd = GET_DSP_GRD (z);",
1890 " res_grd = Sz_grd << i | (unsigned) Sz >> (32 - i);",
1892 " res_grd = SEXT (res_grd);",
1893 " carry = res_grd & 1;",
1895 "else if (i >= 96)",
1900 " res_grd = SIGN32 (Sz_grd);",
1905 " res = Sz >> i | Sz_grd << (32 - i);",
1906 " res_grd = Sz_grd >> i;",
1908 " carry = Sz >> (i - 1) & 1;",
1912 " RAISE_EXCEPTION (SIGILL);",
1915 "COMPUTE_OVERFLOW;",
1916 "greater_equal = 0;",
1918 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1919 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1920 "if (res == 0x80000000)",
1921 " res = 0x7fffffff;",
1923 "DSP_GRD (g) = SIGN32 (res);",
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);",
1932 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1933 "if (res == 0x80000000)",
1934 " res = 0x7fffffff;",
1936 "DSP_GRD (g) = SIGN32 (res);",
1940 "carry = (unsigned) res > (unsigned) Sx;",
1941 "res_grd = Sx_grd - Sy_grd - carry;",
1942 "COMPUTE_OVERFLOW;",
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);",
1951 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1952 "if (res == 0x80000000)",
1953 " res = 0x7fffffff;",
1955 "DSP_GRD (g) = SIGN32 (res);",
1959 "carry = (unsigned) res < (unsigned) Sx;",
1960 "res_grd = Sx_grd + Sy_grd + carry;",
1961 "COMPUTE_OVERFLOW;",
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);",
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;",
1975 "if (res || res_grd)\n",
1976 " DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n",
1978 " DSR |= DSR_MASK_Z | overflow;\n",
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);",
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;",
1994 "if (res || res_grd)\n",
1995 " DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n",
1997 " DSR |= DSR_MASK_Z | overflow;\n",
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);",
2007 "z = 17; /* Ignore result. */",
2009 "carry = (unsigned) res > (unsigned) Sx;",
2010 "res_grd = Sx_grd - Sy_grd - carry;",
2011 "COMPUTE_OVERFLOW;",
2014 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
2016 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
2018 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
2019 "/* FIXME: duplicate code pabs. */",
2021 "res_grd = GET_DSP_GRD (x);",
2027 " carry = (res != 0); /* The manual has a bug here. */",
2028 " res_grd = -res_grd - carry;",
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;",
2036 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2038 "res_grd = GET_DSP_GRD (x);",
2044 " carry = (res != 0); /* The manual has a bug here. */",
2045 " res_grd = -res_grd - carry;",
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;",
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);",
2059 "res = (Sx + 0x8000) & 0xffff0000;",
2060 "carry = (unsigned) res < (unsigned) Sx;",
2061 "res_grd = Sx_grd + carry;",
2062 "COMPUTE_OVERFLOW;",
2065 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2066 "int Sx = DSP_R (x);",
2067 "int Sx_grd = GET_DSP_GRD (x);",
2069 "res = (Sx + 0x8000) & 0xffff0000;",
2070 "carry = (unsigned) res < (unsigned) Sx;",
2071 "res_grd = Sx_grd + carry;",
2072 "COMPUTE_OVERFLOW;",
2076 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2077 "/* FIXME: duplicate code pabs. */",
2081 "greater_equal = DSR_MASK_G;",
2091 " res = 0x7fffffff;",
2094 " overflow = DSR_MASK_V;",
2095 " greater_equal = 0;",
2100 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2104 "greater_equal = DSR_MASK_G;",
2114 " res = 0x7fffffff;",
2117 " overflow = DSR_MASK_V;",
2118 " greater_equal = 0;",
2123 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2124 "/* FIXME: duplicate code prnd. */",
2125 "int Sy = DSP_R (y);",
2126 "int Sy_grd = SIGN32 (Sy);",
2128 "res = (Sy + 0x8000) & 0xffff0000;",
2129 "carry = (unsigned) res < (unsigned) Sy;",
2130 "res_grd = Sy_grd + carry;",
2131 "COMPUTE_OVERFLOW;",
2134 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2135 "int Sy = DSP_R (y);",
2136 "int Sy_grd = SIGN32 (Sy);",
2138 "res = (Sy + 0x8000) & 0xffff0000;",
2139 "carry = (unsigned) res < (unsigned) Sy;",
2140 "res_grd = Sy_grd + carry;",
2141 "COMPUTE_OVERFLOW;",
2144 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2145 "int Sx = DSP_R (x) & 0xffff0000;",
2146 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2150 "else if (Sy >= 128 - 16)",
2151 " res = (unsigned) Sx >> (128 - Sy); /* no sign extension */",
2154 " RAISE_EXCEPTION (SIGILL);",
2157 "goto cond_logical;",
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;",
2174 " res_grd = Sx_grd << Sy | (unsigned) Sx >> (32 - Sy);",
2176 " res_grd = SEXT (res_grd);",
2177 " carry = res_grd & 1;",
2179 "else if (Sy >= 96)",
2184 " res_grd = SIGN32 (Sx_grd);",
2189 " res = Sx >> Sy | Sx_grd << (32 - Sy);",
2190 " res_grd = Sx_grd >> Sy;",
2192 " carry = Sx >> (Sy - 1) & 1;",
2196 " RAISE_EXCEPTION (SIGILL);",
2199 "COMPUTE_OVERFLOW;",
2200 "greater_equal = 0;",
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);",
2209 "carry = (unsigned) res > (unsigned) Sx;",
2210 "res_grd = Sx_grd - Sy_grd - carry;",
2211 "COMPUTE_OVERFLOW;",
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);",
2221 "carry = (unsigned) res > (unsigned) Sy;",
2222 "res_grd = Sy_grd - Sx_grd - carry;",
2223 "COMPUTE_OVERFLOW;",
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);",
2233 "carry = (unsigned) res < (unsigned) Sx;",
2234 "res_grd = Sx_grd + Sy_grd + carry;",
2235 "COMPUTE_OVERFLOW;",
2238 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2239 "res = DSP_R (x) & DSP_R (y);",
2241 "res &= 0xffff0000;",
2243 "if (iword & 0x200)\n",
2244 " goto assign_z;\n",
2248 "greater_equal = 0;",
2251 " DSR |= res >> 26 & DSR_MASK_N;\n",
2253 " DSR |= DSR_MASK_Z;\n",
2254 "goto assign_dc;\n",
2256 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2257 "res = DSP_R (x) ^ DSP_R (y);",
2258 "goto cond_logical;",
2260 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2261 "res = DSP_R (x) | DSP_R (y);",
2262 "goto cond_logical;",
2264 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2265 "int Sx = DSP_R (x);",
2266 "int Sx_grd = GET_DSP_GRD (x);",
2268 "res = Sx - 0x10000;",
2269 "carry = Sx < (INT_MIN + 0x10000);",
2270 "res_grd = Sx_grd - carry;",
2271 "COMPUTE_OVERFLOW;",
2273 "res &= 0xffff0000;",
2275 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2276 "int Sx = DSP_R (x);",
2277 "int Sx_grd = GET_DSP_GRD (x);",
2279 "res = Sx + 0x10000;",
2280 "carry = Sx > (INT_MAX - 0x10000);",
2281 "res_grd = Sx_grd + carry;",
2282 "COMPUTE_OVERFLOW;",
2284 "res &= 0xffff0000;",
2286 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2287 "int Sy = DSP_R (y);",
2288 "int Sy_grd = SIGN32 (Sy);",
2290 "res = Sy - 0x10000;",
2291 "carry = Sy < (INT_MIN + 0x10000);",
2292 "res_grd = Sy_grd - carry;",
2293 "COMPUTE_OVERFLOW;",
2295 "res &= 0xffff0000;",
2297 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2298 "int Sy = DSP_R (y);",
2299 "int Sy_grd = SIGN32 (Sy);",
2301 "res = Sy + 0x10000;",
2302 "carry = Sy > (INT_MAX - 0x10000);",
2303 "res_grd = Sy_grd + carry;",
2304 "COMPUTE_OVERFLOW;",
2306 "res &= 0xffff0000;",
2308 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2313 "greater_equal = 1;",
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;",
2321 "DSP_GRD (g) = SIGN32 (res);",
2322 "/* FIXME: update DSR based on results of multiply! */",
2330 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2331 "unsigned Sx = DSP_R (x);",
2332 "int Sx_grd = GET_DSP_GRD (x);",
2337 " Sx_grd = ~Sx_grd;",
2351 " if (Sx & ~0 << i)",
2359 "res_grd = SIGN32 (res);",
2364 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2365 "unsigned Sy = DSP_R (y);",
2374 " if (Sy & ~0 << i)",
2382 "res_grd = SIGN32 (res);",
2387 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2388 "int Sx = DSP_R (x);",
2389 "int Sx_grd = GET_DSP_GRD (x);",
2392 "carry = res != 0;",
2393 "res_grd = 0 - Sx_grd - carry;",
2394 "COMPUTE_OVERFLOW;",
2397 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2399 "res_grd = GET_DSP_GRD (x);",
2401 "COMPUTE_OVERFLOW;",
2404 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2405 "int Sy = DSP_R (y);",
2406 "int Sy_grd = SIGN32 (Sy);",
2409 "carry = res != 0;",
2410 "res_grd = 0 - Sy_grd - carry;",
2411 "COMPUTE_OVERFLOW;",
2414 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2416 "res_grd = SIGN32 (res);",
2418 "COMPUTE_OVERFLOW;",
2421 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2423 "res_grd = SIGN32 (res);",
2426 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2428 "res_grd = SIGN32 (res);",
2431 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2432 "if (0xa05f >> z & 1)",
2433 " RAISE_EXCEPTION (SIGILL);",
2435 " MACH = DSP_R (z);",
2438 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2439 "if (0xa05f >> z & 1)",
2440 " RAISE_EXCEPTION (SIGILL);",
2442 " MACL = DSP_R (z) = res;",
2446 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2447 "int Sx = DSP_R (x);",
2449 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2450 "res_grd = GET_DSP_GRD (x);",
2453 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2456 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2457 "int Sy = DSP_R (y);",
2459 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2460 "res_grd = SIGN32 (Sy);",
2463 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2469 /* Tables of things to put into enums for sh-opc.h */
2471 const char * const nibble_type_list
[] =
2506 const char * const arg_type_list
[] =
2540 qfunc (const void *va
, const void *vb
)
2548 memcpy (bufa
, a
->code
, 4);
2549 memcpy (bufa
+ 4, a
->code
+ 12, 4);
2552 memcpy (bufb
, b
->code
, 4);
2553 memcpy (bufb
+ 4, b
->code
+ 12, 4);
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
;
2572 qsort (tab
, len
, sizeof (*p
), qfunc
);
2580 for (p
= tab
; p
->name
; p
++)
2582 printf ("%s %-30s\n", p
->code
, p
->name
);
2586 static unsigned short table
[1 << 16];
2588 static int warn_conflicts
= 0;
2591 conflict_warn (int val
, int i
)
2596 fprintf (stderr
, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2597 val
, i
, table
[val
]);
2599 for (ix
= ARRAY_SIZE (tab
); ix
>= 0; ix
--)
2600 if (tab
[ix
].index
== i
|| tab
[ix
].index
== j
)
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'));
2607 if (val
>> 12 == key
)
2608 fprintf (stderr
, " %s -- %s\n", tab
[ix
].code
, tab
[ix
].name
);
2611 for (ix
= ARRAY_SIZE (movsxy_tab
); ix
>= 0; ix
--)
2612 if (movsxy_tab
[ix
].index
== i
|| movsxy_tab
[ix
].index
== j
)
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'));
2619 if (val
>> 12 == key
)
2620 fprintf (stderr
, " %s -- %s\n",
2621 movsxy_tab
[ix
].code
, movsxy_tab
[ix
].name
);
2624 for (ix
= ARRAY_SIZE (ppi_tab
); ix
>= 0; ix
--)
2625 if (ppi_tab
[ix
].index
== i
|| ppi_tab
[ix
].index
== j
)
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'));
2632 if (val
>> 12 == key
)
2633 fprintf (stderr
, " %s -- %s\n",
2634 ppi_tab
[ix
].code
, ppi_tab
[ix
].name
);
2638 /* Take an opcode, expand all varying fields in it out and fill all the
2639 right entries in 'table' with the opcode index. */
2642 expand_opcode (int val
, int i
, const char *s
)
2646 if (warn_conflicts
&& table
[val
] != 0)
2647 conflict_warn (val
, i
);
2657 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
2661 /* Consume an arbitrary number of ones and zeros. */
2663 j
= (j
<< 1) + (s
[m
++] - '0');
2664 } while (s
[m
] == '0' || s
[m
] == '1');
2665 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
2667 case 'N': /* NN -- four-way fork */
2668 for (j
= 0; j
< 4; j
++)
2669 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
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);
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);
2679 case '?': /* Seven-way "wildcard" fork for movxy */
2680 expand_opcode ((val
<< 2), i
, s
+ 2);
2681 for (j
= 1; j
< 4; j
++)
2683 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2684 expand_opcode ((val
<< 2) | (j
+ 16), i
, s
+ 2);
2687 case 'i': /* eg. "i8*1" */
2688 case '.': /* "...." is a wildcard */
2691 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2692 for (j
= 0; j
< 16; j
++)
2693 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2696 /* eeee -- even numbered register:
2698 for (j
= 0; j
< 15; j
+= 2)
2699 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
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);
2710 GGGG -- two-way fork */
2711 for (j
= 13; j
<= 15; j
+=2)
2712 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
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);
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);
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);
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);
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);
2744 /* vv(VV) -- 4(16) way fork. */
2745 /* Vector register fv0/4/8/12. */
2748 /* 2 vector registers. */
2749 for (j
= 0; j
< 15; j
++)
2750 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2754 /* 1 vector register. */
2755 for (j
= 0; j
< 4; j
+= 1)
2756 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2763 /* Print the jump table used to index an opcode into a switch
2767 dumptable (const char *name
, int size
, int start
)
2774 printf ("unsigned short %s[%d]={\n", name
, size
);
2775 while (i
< start
+ size
)
2779 printf ("/* 0x%x */\n", i
);
2786 printf ("%2d", table
[i
+ j
+ k
]);
2804 static int index
= 1;
2807 for (; p
->name
; p
++)
2810 expand_opcode (0, p
->index
, p
->code
);
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. */
2819 expand_ppi_movxy (void)
2823 for (i
= 0xf000; i
< 0xf400; i
++)
2825 table
[i
+ 0x800] = table
[0xf800];
2829 gensim_caselist (op
*p
)
2831 for (; p
->name
; p
++)
2837 const char *s
= p
->code
;
2839 printf (" /* %s %s */\n", p
->name
, p
->code
);
2840 printf (" case %d: \n", p
->index
);
2848 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2853 /* Wildcard expansion, nothing to do here. */
2857 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2861 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2873 printf (" int n = (iword >> 8) & 0xf;\n");
2878 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2882 if (s
[1] == 'y') /* xy */
2884 printf (" int n = (iword & 3) ? \n");
2885 printf (" ((iword >> 9) & 1) + 4 : \n");
2886 printf (" REG_xy ((iword >> 8) & 3);\n");
2889 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2894 if (s
[1] == 'x') /* yx */
2896 printf (" int n = (iword & 0xc) ? \n");
2897 printf (" ((iword >> 8) & 1) + 6 : \n");
2898 printf (" REG_yx ((iword >> 8) & 3);\n");
2901 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2910 printf (" int m = (iword >> 4) & 0xf;\n");
2914 if (s
[1] == 'Y') /* XY */
2916 printf (" int m = (iword & 3) ? \n");
2917 printf (" ((iword >> 7) & 1) + 8 : \n");
2918 printf (" DSP_xy ((iword >> 6) & 3);\n");
2921 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2925 if (s
[1] == 'x') /* ax */
2927 printf (" int m = (iword & 3) ? \n");
2928 printf (" 7 - ((iword >> 6) & 2) : \n");
2929 printf (" DSP_ax ((iword >> 6) & 3);\n");
2932 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2936 if (s
[1] == 'X') /* YX */
2938 printf (" int m = (iword & 0xc) ? \n");
2939 printf (" ((iword >> 6) & 1) + 10 : \n");
2940 printf (" DSP_yx ((iword >> 6) & 3);\n");
2943 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2947 if (s
[1] == 'Y') /* AY */
2949 printf (" int m = (iword & 0xc) ? \n");
2950 printf (" 7 - ((iword >> 5) & 2) : \n");
2951 printf (" DSP_ay ((iword >> 6) & 3);\n");
2954 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2959 printf (" int i = (iword & 0x");
2965 "gensim_caselist: Unknown char '%c' in %s\n",
2986 "gensim_caselist: Unknown char '%c' in %s\n",
2990 case '.': /* eg. "i12." */
3007 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3008 sextbit
- 1, sextbit
- 1);
3012 printf (" TB (m,n);\n");
3014 printf (" TL (m);\n");
3016 printf (" TL (n);\n");
3021 for (r
= p
->refs
; *r
; r
++)
3023 if (*r
== 'f') printf (" CREF (15);\n");
3027 printf (" int i = n;\n");
3029 printf (" CREF (i);\n");
3030 printf (" } while (i-- > 0);\n");
3036 printf (" int i = n;\n");
3038 printf (" CREF (i);\n");
3039 printf (" } while (i++ < 14);\n");
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");
3051 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3055 printf (" %s\n", p
->stuff
[j
]);
3063 for (r
= p
->defs
; *r
; r
++)
3065 if (*r
== 'f') printf (" CDEF (15);\n");
3069 printf (" int i = n;\n");
3071 printf (" CDEF (i);\n");
3072 printf (" } while (i-- > 0);\n");
3078 printf (" int i = n;\n");
3080 printf (" CDEF (i);\n");
3081 printf (" } while (i++ < 14);\n");
3084 if (*r
== '0') printf (" CDEF (0);\n");
3085 if (*r
== 'n') printf (" CDEF (n);\n");
3086 if (*r
== 'm') printf (" CDEF (m);\n");
3090 printf (" break;\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");
3113 gensim_caselist (tab
);
3114 gensim_caselist (movsxy_tab
);
3116 printf (" default:\n");
3118 printf (" RAISE_EXCEPTION (SIGILL);\n");
3129 for (p
= tab
; p
->name
; p
++)
3131 const char *s
= p
->name
;
3132 printf ("#define OPC_");
3135 printf ("%c", tolower (*s
));
3144 printf (" %d\n",p
->index
);
3148 static int ppi_index
;
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. */
3155 expand_ppi_code (int val
, int i
, const char *s
)
3162 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n", s
[0]);
3167 if (warn_conflicts
&& table
[val
] != 0)
3168 conflict_warn (val
, i
);
3170 /* The last four bits are disregarded for the switch table. */
3174 /* Four-bit expansion. */
3175 for (j
= 0; j
< 16; j
++)
3176 expand_ppi_code ((val
<< 4) + j
, i
, s
+ 4);
3180 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3183 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3188 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3189 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
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);
3200 ppi_filltable (void)
3205 for (p
= ppi_tab
; p
->name
; p
++)
3207 p
->index
= ppi_index
++;
3208 expand_ppi_code (0, p
->index
, p
->code
);
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");
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");
3226 printf (" if (res_grd & 0x80) \\\n");
3228 printf (" res = 0x80000000; \\\n");
3229 printf (" res_grd |= 0xff; \\\n");
3231 printf (" else \\\n");
3233 printf (" res = 0x7fffffff; \\\n");
3234 printf (" res_grd &= ~0xff; \\\n");
3236 printf (" overflow = 0; \\\n");
3238 printf ("} while (0)\n");
3240 printf ("#define ADD_SUB_GE \\\n");
3241 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3243 printf ("static void\n");
3244 printf ("ppi_insn (int iword)\n");
3246 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3247 printf (" static char const e_tab[] = { 8, 9, 10, 5};\n");
3248 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3249 printf (" static char const f_tab[] = {10, 11, 8, 5};\n");
3250 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3251 printf (" static char const x_tab[] = { 8, 9, 7, 5};\n");
3252 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3253 printf (" static char const y_tab[] = {10, 11, 12, 14};\n");
3254 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3255 printf (" static char const g_tab[] = {12, 14, 7, 5};\n");
3256 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3257 printf (" static char const u_tab[] = { 8, 10, 7, 5};\n");
3259 printf (" int z;\n");
3260 printf (" int res, res_grd;\n");
3261 printf (" int carry, overflow, greater_equal;\n");
3263 printf (" switch (ppi_table[iword >> 4]) {\n");
3265 for (; p
->name
; p
++)
3270 const char *s
= p
->code
;
3272 printf (" /* %s %s */\n", p
->name
, p
->code
);
3273 printf (" case %d: \n", p
->index
);
3276 for (shift
= 16; *s
; )
3281 printf (" int i = (iword >> 4) & 0x7f;\n");
3291 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3297 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3298 printf ("\treturn;\n");
3300 printf (" case %d: \n", p
->index
+ 1);
3312 printf (" z = iword & 0xf;\n");
3320 else if (havedecl
== 2)
3322 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3327 (havedecl
== 2 ? " " : ""),
3335 printf (" if (iword & 0x200)\n");
3336 printf (" goto assign_z;\n");
3338 printf (" break;\n");
3342 printf (" default:\n");
3344 printf (" RAISE_EXCEPTION (SIGILL);\n");
3345 printf (" return;\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");
3352 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3353 printf (" assign_dc:\n");
3354 printf (" switch (DSR >> 1 & 7)\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");
3369 printf (" assign_z:\n");
3370 printf (" if (0xa05f >> z & 1)\n");
3372 printf (" RAISE_EXCEPTION (SIGILL);\n");
3373 printf (" return;\n");
3375 printf (" DSP_R (z) = res;\n");
3376 printf (" DSP_GRD (z) = res_grd;\n");
3381 main (int ac
, char *av
[])
3383 /* Verify the table before anything else. */
3386 for (p
= tab
; p
->name
; p
++)
3388 /* Check that the code field contains 16 bits. */
3389 if (strlen (p
->code
) != 16)
3391 fprintf (stderr
, "Code `%s' length wrong (%zu) for `%s'\n",
3392 p
->code
, strlen (p
->code
), p
->name
);
3398 /* Now generate the requested data. */
3401 if (ac
> 2 && strcmp (av
[2], "-w") == 0)
3405 if (strcmp (av
[1], "-t") == 0)
3409 else if (strcmp (av
[1], "-d") == 0)
3413 else if (strcmp (av
[1], "-s") == 0)
3416 dumptable ("sh_jump_table", 1 << 16, 0);
3418 memset (table
, 0, sizeof table
);
3419 filltable (movsxy_tab
);
3420 expand_ppi_movxy ();
3421 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3423 memset (table
, 0, sizeof table
);
3425 dumptable ("ppi_table", 1 << 12, 0);
3427 else if (strcmp (av
[1], "-x") == 0)
3430 filltable (movsxy_tab
);
3433 else if (strcmp (av
[1], "-p") == 0)
3440 fprintf (stderr
, "Opcode table generation no longer supported.\n");