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
44 const char * const defs
;
45 const char * const refs
;
46 const char * const name
;
47 const char * const code
;
48 const char * const stuff
[MAX_NR_STUFF
];
56 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
60 " UNDEF(n); /* see #ifdef PARANOID */",
65 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
71 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
74 "SET_SR_T (ult < R[n]);",
76 "SET_SR_T (T || (R[n] < ult));",
80 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
83 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
88 { "0", "0", "and #<imm>,R0", "11001001i8*1....",
93 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
98 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
101 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
105 { "", "", "bf <bdisp8>", "10001011i8p1....",
107 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
109 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
115 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
117 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
119 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
121 " Delay_Slot (PC + 2);",
126 { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
128 "/* 32-bit logical bit-manipulation instructions. */",
129 "int word2 = RIAT (nip);",
130 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
131 "i >>= 4; /* BOGUS: Using only three bits of 'i'. */",
132 "/* MSB of 'i' must be zero. */",
134 " RAISE_EXCEPTION (SIGILL);",
136 "do_blog_insn (1 << i, (word2 & 0xfff) + R[n],",
137 " (word2 >> 12) & 0xf, memory, maskb);",
138 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
141 { "", "", "bra <bdisp12>", "1010i12.........",
143 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
144 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
146 "Delay_Slot (PC + 2);",
150 { "", "n", "braf <REG_N>", "0000nnnn00100011",
152 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
153 "SET_NIP (PC + 4 + R[n]);",
155 "Delay_Slot (PC + 2);",
159 { "", "", "bsr <bdisp12>", "1011i12.........",
161 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
162 "PR = PH2T (PC + 4);",
163 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
165 "Delay_Slot (PC + 2);",
169 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
171 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
172 "PR = PH2T (PC) + 4;",
173 "SET_NIP (PC + 4 + R[n]);",
175 "Delay_Slot (PC + 2);",
179 { "", "", "bt <bdisp8>", "10001001i8p1....",
181 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
183 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
189 { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
191 "/* MSB of 'i' is true for load, false for store. */",
194 " R[m] |= (1 << i);",
196 " R[m] &= ~(1 << i);",
198 " SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
201 { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
203 "/* MSB of 'i' is true for set, false for clear. */",
205 " R[m] &= ~(1 << i);",
207 " R[m] |= (1 << (i - 8));",
210 { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
212 "if (R[n] < -128 || R[n] > 127) {",
217 " else if (R[n] < -128)",
222 { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
224 "if (R[n] < -32768 || R[n] > 32767) {",
227 " if (R[n] > 32767)",
229 " else if (R[n] < -32768)",
234 { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
236 "if (R[n] < -256 || R[n] > 255) {",
243 { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
245 "if (R[n] < -65536 || R[n] > 65535) {",
252 { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
254 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
256 " R[n] = 0x7fffffff;",
257 "else if (R0 == -1 && R[n] == 0x80000000)",
258 " R[n] = 0x7fffffff;",
263 { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
265 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
267 " R[n] = 0xffffffff;",
268 "/* FIXME: The result may be implementation-defined if it is outside */",
269 "/* the range of signed int (i.e. if R[n] was negative and R0 == 1). */",
270 "else R[n] = R[n] / (unsigned int) R0;",
274 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
276 "R[n] = (R[n] * R0) & 0xffffffff;",
280 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
282 "int regn = (R[n] >> 2) & 0x1f;",
283 "int bankn = (R[n] >> 7) & 0x1ff;",
285 " regn = 19; /* FIXME what should happen? */",
286 "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
290 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
292 "int regn = (R[n] >> 2) & 0x1f;",
293 "int bankn = (R[n] >> 7) & 0x1ff;",
295 " regn = 19; /* FIXME what should happen? */",
296 "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
299 { "", "", "resbank", "0000000001011011",
302 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
303 /* FIXME: cdef all */
304 "if (BO) { /* Bank Overflow */",
305 /* FIXME: how do we know when to reset BO? */
306 " for (i = 0; i <= 14; i++) {",
307 " R[i] = RLAT (R[15]);",
311 " PR = RLAT (R[15]);",
314 " GBR = RLAT (R[15]);",
317 " MACH = RLAT (R[15]);",
320 " MACL = RLAT (R[15]);",
324 "else if (BANKN == 0) /* Bank Underflow */",
325 " RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */
327 " SET_BANKN (BANKN - 1);",
328 " for (i = 0; i <= 14; i++)",
329 " R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
330 " MACH = saved_state.asregs.regstack[BANKN].regs[15];",
331 " PR = saved_state.asregs.regstack[BANKN].regs[17];",
332 " GBR = saved_state.asregs.regstack[BANKN].regs[18];",
333 " MACL = saved_state.asregs.regstack[BANKN].regs[19];",
337 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
339 "/* Push Rn...R0 (if n==15, push pr and R14...R0). */",
344 " WLAT (R[15], PR);",
346 " WLAT (R[15], R[n]);",
347 "} while (n-- > 0);",
350 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
352 "/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */",
357 " PR = RLAT (R[15]);",
359 " R[i] = RLAT (R[15]);",
361 "} while (i++ < n);",
364 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
366 "/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */
372 " WLAT (R[15], PR);",
374 " WLAT (R[15], R[i]);",
375 "} while (i-- > n);",
378 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
380 "/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */
384 " PR = RLAT (R[15]);",
386 " R[n] = RLAT (R[15]);",
388 "} while (n++ < 15);",
391 { "", "", "nott", "0000000001101000",
393 "SET_SR_T (T == 0);",
397 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
399 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
401 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
403 " Delay_Slot (PC + 2);",
408 { "", "", "clrmac", "0000000000101000",
415 { "", "", "clrs", "0000000001001000",
421 { "", "", "clrt", "0000000000001000",
428 { "", "", "clrdmxy", "0000000010001000",
430 "saved_state.asregs.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
434 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
436 "SET_SR_T (R0 == SEXT (i));",
439 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
441 "SET_SR_T (R[n] == R[m]);",
444 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
446 "SET_SR_T (R[n] >= R[m]);",
449 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
451 "SET_SR_T (R[n] > R[m]);",
454 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
456 "SET_SR_T (UR[n] > UR[m]);",
459 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
461 "SET_SR_T (UR[n] >= UR[m]);",
464 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
466 "SET_SR_T (R[n] > 0);",
469 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
471 "SET_SR_T (R[n] >= 0);",
474 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
476 "ult = R[n] ^ R[m];",
477 "SET_SR_T (((ult & 0xff000000) == 0)",
478 " | ((ult & 0xff0000) == 0)",
479 " | ((ult & 0xff00) == 0)",
480 " | ((ult & 0xff) == 0));",
484 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
486 "SET_SR_Q ((R[n] & sbit) != 0);",
487 "SET_SR_M ((R[m] & sbit) != 0);",
488 "SET_SR_T (M != Q);",
492 { "", "", "div0u", "0000000000011001",
500 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
502 "div1 (&R0, m, n/*, T*/);",
506 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
508 "dmul_s (R[n], R[m]);",
512 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
514 "dmul_u (R[n], R[m]);",
518 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
521 "SET_SR_T (R[n] == 0);",
525 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
527 "R[n] = SEXT (R[m]);",
530 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
532 "R[n] = SEXTW (R[m]);",
536 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
538 "R[n] = (R[m] & 0xff);",
541 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
543 "R[n] = (R[m] & 0xffff);",
548 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
556 " u.i &= 0x7fffffff;",
562 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
569 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
571 "FP_CMP (n, ==, m);",
575 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
582 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
584 "if (! FPSCR_PR || n & 1)",
585 " RAISE_EXCEPTION (SIGILL);",
600 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
602 "if (! FPSCR_PR || n & 1)",
603 " RAISE_EXCEPTION (SIGILL);",
618 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
621 "/* FIXME: check for DP and (n & 1) == 0? */",
626 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
629 " RAISE_EXCEPTION (SIGILL);",
633 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
634 " RAISE_EXCEPTION (SIGILL);",
635 " /* FIXME: check for nans and infinities. */",
636 " fsum += FR (v1+0) * FR (v2+0);",
637 " fsum += FR (v1+1) * FR (v2+1);",
638 " fsum += FR (v1+2) * FR (v2+2);",
639 " fsum += FR (v1+3) * FR (v2+3);",
640 " SET_FR (v1+3, fsum);",
646 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
648 "SET_FR (n, (float) 0.0);",
649 "/* FIXME: check for DP and (n & 1) == 0? */",
654 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
656 "SET_FR (n, (float) 1.0);",
657 "/* FIXME: check for DP and (n & 1) == 0? */",
662 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
675 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
679 " SET_DR (n, (double) FPUL);",
682 " SET_FR (n, (float) FPUL);",
688 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
690 "SET_FR (n, FR (m) * FR (0) + FR (n));",
691 "/* FIXME: check for DP and (n & 1) == 0? */",
696 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
700 " int ni = XD_TO_XF (n);",
701 " int mi = XD_TO_XF (m);",
702 " SET_XF (ni + 0, XF (mi + 0));",
703 " SET_XF (ni + 1, XF (mi + 1));",
707 " SET_FR (n, FR (m));",
712 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
722 " WLAT (R[n], FI (m));",
727 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
737 " SET_FI (n, RLAT (R[m]));",
742 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
744 "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
745 " and mov.bwl <REG_N>, @(disp12,<REG_M>)",
746 " and mov.bwl @(disp12,<REG_N>),<REG_M>",
747 " and movu.bw @(disp12,<REG_N>),<REG_M>. */",
748 "int word2 = RIAT (nip);",
749 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
750 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
752 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
756 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
767 " SET_FI (n, RLAT (R[m]));",
773 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
785 " WLAT (R[n], FI (m));",
790 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
795 " RDAT (R[0]+R[m], n);",
800 " SET_FI (n, RLAT (R[0] + R[m]));",
805 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
810 " WDAT (R[0]+R[n], m);",
815 " WLAT ((R[0]+R[n]), FI (m));",
821 See fmov instructions above for move to/from extended fp registers. */
824 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
831 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
839 " u.i ^= 0x80000000;",
845 { "", "", "fpchg", "1111011111111101",
847 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
852 { "", "", "frchg", "1111101111111101",
855 " RAISE_EXCEPTION (SIGILL);",
856 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
857 " RAISE_EXCEPTION (SIGILL);",
859 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
864 { "", "", "fsca", "1111eeee11111101",
867 " RAISE_EXCEPTION (SIGILL);",
868 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
869 " RAISE_EXCEPTION (SIGILL);",
872 " SET_FR (n, fsca_s (FPUL, &sin));",
873 " SET_FR (n+1, fsca_s (FPUL, &cos));",
879 { "", "", "fschg", "1111001111111101",
881 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
886 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
888 "FP_UNARY (n, sqrt);",
893 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
896 " RAISE_EXCEPTION (SIGILL);",
897 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
898 " RAISE_EXCEPTION (SIGILL);",
900 " SET_FR (n, fsrra_s (FR (n)));",
905 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
912 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
916 " if (DR (n) != DR (n)) /* NaN */",
917 " FPUL = 0x80000000;",
919 " FPUL = (int) DR (n);",
922 "if (FR (n) != FR (n)) /* NaN */",
923 " FPUL = 0x80000000;",
925 " FPUL = (int) FR (n);",
930 { "", "", "ftrv <FV_N>", "1111vv0111111101",
933 " RAISE_EXCEPTION (SIGILL);",
936 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
937 " RAISE_EXCEPTION (SIGILL);",
938 " /* FIXME not implemented. */",
939 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
945 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
957 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
959 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
960 "SET_NIP (PT2H (R[n]));",
962 "Delay_Slot (PC + 2);",
966 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
968 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
969 "PR = PH2T (PC + 4);",
971 " gotcall (PR, R[n]);",
972 "SET_NIP (PT2H (R[n]));",
974 "Delay_Slot (PC + 2);",
977 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
979 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
980 "PR = PH2T (PC + 2);",
982 " gotcall (PR, R[n]);",
983 "SET_NIP (PT2H (R[n]));",
986 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
988 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
989 "PR = PH2T (PC + 2);",
991 " gotcall (PR, i + TBR);",
992 "SET_NIP (PT2H (i + TBR));",
996 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
999 "/* FIXME: user mode */",
1002 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
1005 "/* FIXME: user mode */",
1008 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
1013 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
1016 " DBR = R[n]; /* priv mode */",
1018 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1021 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
1024 " SGR = R[n]; /* priv mode */",
1026 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1029 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
1031 "if (SR_MD)", /* FIXME? */
1032 " TBR = R[n]; /* priv mode */",
1034 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1037 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
1040 "CREG (m) = RLAT (R[n]);",
1042 "/* FIXME: user mode */",
1045 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
1048 "SET_SR (RLAT (R[n]));",
1050 "/* FIXME: user mode */",
1053 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
1056 "SET_MOD (RLAT (R[n]));",
1060 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
1063 "{ /* priv mode */",
1065 " DBR = RLAT (R[n]);",
1069 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1072 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
1075 "{ /* priv mode */",
1077 " SGR = RLAT (R[n]);",
1081 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1086 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
1088 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
1091 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
1093 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
1098 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
1101 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
1102 "CHECK_INSN_PTR (insn_ptr);",
1106 { "", "", "ldrc #<imm>", "10001010i8*1....",
1109 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
1110 "CHECK_INSN_PTR (insn_ptr);",
1115 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
1120 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
1123 "SREG (m) = RLAT (R[n]);",
1127 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
1128 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
1130 "SET_FPSCR (R[n]);",
1133 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
1134 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
1137 "SET_FPSCR (RLAT (R[n]));",
1142 { "", "", "ldtlb", "0000000000111000",
1144 "/* We don't implement cache or tlb, so this is a noop. */",
1148 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
1150 "macl (&R0, memory, n, m);",
1154 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
1156 "macw (&R0, memory, n, m, endianw);",
1160 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
1165 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
1167 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1168 "R[n] = ((i << 24) >> 12) | RIAT (nip);",
1169 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
1172 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
1174 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1175 "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
1176 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
1179 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
1185 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
1188 "R0 = RSBAT (i + GBR);",
1192 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
1195 "R0 = RSBAT (i + R[m]);",
1199 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
1202 "R[n] = RSBAT (R0 + R[m]);",
1206 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
1209 "R[n] = RSBAT (R[m]);",
1214 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
1218 "R0 = RSBAT (R[n]);",
1222 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
1225 "WBAT (R[n], R[m]);",
1228 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
1231 "WBAT (i + GBR, R0);",
1234 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
1237 "WBAT (i + R[m], R0);",
1240 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
1243 "WBAT (R[n] + R0, R[m]);",
1246 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
1248 /* Allow for the case where m == n. */
1255 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
1262 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
1265 "R[n] = RSBAT (R[m]);",
1270 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
1273 "R0 = RLAT (i + GBR);",
1277 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
1279 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1281 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
1285 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1288 "R[n] = RLAT (i + R[m]);",
1292 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1295 "R[n] = RLAT (R0 + R[m]);",
1299 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1302 "R[n] = RLAT (R[m]);",
1307 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1311 "R0 = RLAT (R[n]);",
1315 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1318 "R[n] = RLAT (R[m]);",
1322 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1325 "WLAT (i + GBR, R0);",
1328 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1331 "WLAT (i + R[n], R[m]);",
1334 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1337 "WLAT (R0 + R[n], R[m]);",
1340 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1342 /* Allow for the case where m == n. */
1349 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1356 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1359 "WLAT (R[n], R[m]);",
1363 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1366 "R0 = RSWAT (i + GBR);",
1370 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1372 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1374 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1378 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1381 "R0 = RSWAT (i + R[m]);",
1385 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1388 "R[n] = RSWAT (R0 + R[m]);",
1392 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1395 "R[n] = RSWAT (R[m]);",
1400 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1404 "R0 = RSWAT (R[n]);",
1408 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1411 "R[n] = RSWAT (R[m]);",
1415 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1418 "WWAT (i + GBR, R0);",
1421 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1424 "WWAT (i + R[m], R0);",
1427 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1430 "WWAT (R0 + R[n], R[m]);",
1433 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1435 /* Allow for the case where m == n. */
1442 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1449 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1452 "WWAT (R[n], R[m]);",
1456 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1458 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1459 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1463 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1465 "/* We don't simulate cache, so this insn is identical to mov. */",
1467 "WLAT (R[n], R[0]);",
1471 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1475 "/* if (T) R0 -> (Rn) */",
1477 " WLAT (R[n], R[0]);",
1483 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1488 "R[0] = RLAT (R[n]);",
1489 "/* if (interrupt/exception) 0 -> LDST */",
1490 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1494 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1499 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1504 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1507 "int e = target_little_endian ? 3 : 0;",
1509 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) +",
1510 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1514 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1517 "int e = target_little_endian ? 3 : 0;",
1519 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) +",
1520 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1525 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1527 "MACL = ((int) R[n]) * ((int) R[m]);",
1530 #if 0 /* FIXME: The above cast to int is not really portable.
1531 It should be replaced by a SEXT32 macro. */
1532 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1534 "MACL = R[n] * R[m];",
1539 /* muls.w - see muls */
1540 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1542 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1546 /* mulu.w - see mulu */
1547 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1549 "MACL = (((unsigned int) (unsigned short) R[n])",
1550 " * ((unsigned int) (unsigned short) R[m]));",
1554 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1560 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1563 "SET_SR_T (ult > 0);",
1564 "R[n] = ult - R[m];",
1565 "SET_SR_T (T || (R[n] > ult));",
1569 { "", "", "nop", "0000000000001001",
1575 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1582 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1584 "/* Except for the effect on the cache - which is not simulated -",
1585 " this is like a nop. */",
1589 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1591 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1592 "/* FIXME: Cache not implemented */",
1596 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1598 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1599 "/* FIXME: Cache not implemented */",
1603 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1605 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1606 "/* FIXME: Cache not implemented */",
1610 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1615 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1620 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1623 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1627 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1629 "/* Except for the effect on the cache - which is not simulated -",
1630 " this is like a nop. */",
1635 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1637 "/* Except for the effect on the cache - which is not simulated -",
1638 " this is like a nop. */",
1643 { "", "", "synco", "0000000010101011",
1645 "/* Except for the effect on the pipeline - which is not simulated -",
1646 " this is like a nop. */",
1650 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1653 "R[n] = (R[n] << 1) | T;",
1658 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1661 "R[n] = (UR[n] >> 1) | (T << 31);",
1666 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1668 "SET_SR_T (R[n] < 0);",
1674 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1676 "SET_SR_T (R[n] & 1);",
1677 "R[n] = UR[n] >> 1;",
1678 "R[n] |= (T << 31);",
1682 { "", "", "rte", "0000000000101011",
1687 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1689 "SET_SR (RLAT (R[15]) & 0x3f3);",
1691 "Delay_Slot (PC + 2);",
1693 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1695 "SET_NIP (PT2H (SPC));",
1697 "Delay_Slot (PC + 2);",
1702 { "", "", "rts", "0000000000001011",
1704 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1705 "SET_NIP (PT2H (PR));",
1707 "Delay_Slot (PC + 2);",
1710 { "", "", "rts/n", "0000000001101011",
1712 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1713 "SET_NIP (PT2H (PR));",
1716 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1718 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1721 "SET_NIP (PT2H (PR));",
1726 { "", "", "setdmx", "0000000010011000",
1728 "saved_state.asregs.sr |= SR_MASK_DMX;"
1729 "saved_state.asregs.sr &= ~SR_MASK_DMY;"
1734 { "", "", "setdmy", "0000000011001000",
1736 "saved_state.asregs.sr |= SR_MASK_DMY;"
1737 "saved_state.asregs.sr &= ~SR_MASK_DMX;"
1742 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1747 { "", "", "setrc #<imm>", "10000010i8*1....",
1749 /* It would be more realistic to let loop_start point to some static
1750 memory that contains an illegal opcode and then give a bus error when
1751 the loop is eventually encountered, but it seems not only simpler,
1752 but also more debugging-friendly to just catch the failure here. */
1753 "if (BUSERROR (RS | RE, maskw))",
1754 " RAISE_EXCEPTION (SIGILL);",
1757 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1758 " CHECK_INSN_PTR (insn_ptr);",
1763 { "", "", "sets", "0000000001011000",
1769 { "", "", "sett", "0000000000011000",
1775 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1777 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1781 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1783 "SET_SR_T (R[n] < 0);",
1788 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1790 "SET_SR_T (R[n] & 1);",
1791 "R[n] = R[n] >> 1;",
1795 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1797 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1801 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1803 "SET_SR_T (R[n] < 0);",
1808 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1813 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1818 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1824 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1826 "SET_SR_T (R[n] & 1);",
1827 "R[n] = UR[n] >> 1;",
1831 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1833 "R[n] = UR[n] >> 2;",
1836 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1838 "R[n] = UR[n] >> 8;",
1841 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1843 "R[n] = UR[n] >> 16;",
1847 { "", "", "sleep", "0000000000011011",
1849 "nip += trap (sd, 0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1853 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1859 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1862 " R[n] = SGR; /* priv mode */",
1864 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1867 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1870 " R[n] = DBR; /* priv mode */",
1872 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1875 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1877 "if (SR_MD)", /* FIXME? */
1878 " R[n] = TBR; /* priv mode */",
1880 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1883 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1887 "WLAT (R[n], CREG (m));",
1890 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1893 "{ /* priv mode */",
1896 " WLAT (R[n], SGR);",
1899 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1902 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1905 "{ /* priv mode */",
1908 " WLAT (R[n], DBR);",
1911 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1915 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1920 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1924 "WLAT (R[n], SREG (m));",
1928 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1934 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1937 "SET_SR_T (ult > R[n]);",
1938 "R[n] = ult - R[m];",
1939 "SET_SR_T (T || (R[n] > ult));",
1943 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1945 "ult = R[n] - R[m];",
1946 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1951 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1953 "R[n] = ((R[m] & 0xffff0000)",
1954 " | ((R[m] << 8) & 0xff00)",
1955 " | ((R[m] >> 8) & 0x00ff));",
1958 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1960 "R[n] = (((R[m] << 16) & 0xffff0000)",
1961 " | ((R[m] >> 16) & 0x00ffff));",
1965 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1968 "ult = RBAT (R[n]);",
1969 "SET_SR_T (ult == 0);",
1970 "WBAT (R[n],ult|0x80);",
1974 { "0", "", "trapa #<imm>", "11000011i8*1....",
1976 "long imm = 0xff & i;",
1977 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1978 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1979 " nip += trap (sd, i, &R0, PC, memory, maskl, maskw, endianw);",
1984 " WLAT (R[15], GET_SR ());",
1986 " WLAT (R[15], PH2T (PC + 2));",
1988 "else if (!SR_BL) {",
1989 " SSR = GET_SR ();",
1990 " SPC = PH2T (PC + 2);",
1991 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1992 " /* FIXME: EXPEVT = 0x00000160; */",
1994 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1999 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
2001 "SET_SR_T ((R[n] & R[m]) == 0);",
2004 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
2006 "SET_SR_T ((R0 & i) == 0);",
2009 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
2012 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
2016 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
2021 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
2026 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
2029 "ult = RBAT (GBR+R0);",
2031 "WBAT (GBR + R0, ult);",
2035 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
2037 "R[n] = (((R[n] >> 16) & 0xffff)",
2038 " | ((R[m] << 16) & 0xffff0000));",
2043 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
2045 "divl (0, R[n], R[m]);",
2048 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
2050 "divl (0, R[n], R[m]);",
2058 static op movsxy_tab
[] =
2060 /* If this is disabled, the simulator speeds up by about 12% on a
2061 450 MHz PIII - 9% with ACE_FAST.
2062 Maybe we should have separate simulator loops? */
2064 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
2068 "DSP_R (m) = RSWAT (R[n]) << 16;",
2069 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2072 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
2075 "DSP_R (m) = RSWAT (R[n]) << 16;",
2076 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2079 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
2082 "DSP_R (m) = RSWAT (R[n]) << 16;",
2083 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2087 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
2090 "DSP_R (m) = RSWAT (R[n]) << 16;",
2091 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2095 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
2099 "DSP_R (m) = RSWAT (R[n]);",
2102 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
2105 "DSP_R (m) = RSWAT (R[n]);",
2108 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
2111 "DSP_R (m) = RSWAT (R[n]);",
2115 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
2118 "DSP_R (m) = RSWAT (R[n]);",
2122 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
2126 "WWAT (R[n], DSP_R (m) >> 16);",
2129 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
2132 "WWAT (R[n], DSP_R (m) >> 16);",
2135 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
2138 "WWAT (R[n], DSP_R (m) >> 16);",
2142 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
2145 "WWAT (R[n], DSP_R (m) >> 16);",
2149 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
2153 "WWAT (R[n], SEXT (DSP_R (m)));",
2156 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
2159 "WWAT (R[n], SEXT (DSP_R (m)));",
2162 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
2165 "WWAT (R[n], SEXT (DSP_R (m)));",
2169 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
2172 "WWAT (R[n], SEXT (DSP_R (m)));",
2176 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
2180 "DSP_R (m) = RLAT (R[n]);",
2181 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2184 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
2187 "DSP_R (m) = RLAT (R[n]);",
2188 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2191 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
2194 "DSP_R (m) = RLAT (R[n]);",
2195 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2199 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
2202 "DSP_R (m) = RLAT (R[n]);",
2203 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2207 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
2211 "WLAT (R[n], DSP_R (m));",
2214 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
2217 "WLAT (R[n], DSP_R (m));",
2220 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
2223 "WLAT (R[n], DSP_R (m));",
2227 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
2230 "WLAT (R[n], DSP_R (m));",
2234 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
2238 "WLAT (R[n], SEXT (DSP_R (m)));",
2241 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
2244 "WLAT (R[n], SEXT (DSP_R (m)));",
2247 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
2250 "WLAT (R[n], SEXT (DSP_R (m)));",
2254 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
2257 "WLAT (R[n], SEXT (DSP_R (m)));",
2261 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
2263 "DSP_R (m) = RSWAT (R[n]) << 16;",
2266 " iword &= 0xfd53; goto top;",
2270 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
2272 "DSP_R (m) = RLAT (R[n]);",
2275 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
2277 "DSP_R (m) = RSWAT (R[n]) << 16;",
2278 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2281 " iword &= 0xfd53; goto top;",
2285 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
2287 "DSP_R (m) = RLAT (R[n]);",
2288 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2291 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
2293 "DSP_R (m) = RSWAT (R[n]) << 16;",
2294 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2297 " iword &= 0xfd53; goto top;",
2301 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
2303 "DSP_R (m) = RLAT (R[n]);",
2304 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2307 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
2309 "WWAT (R[n], DSP_R (m) >> 16);",
2312 " iword &= 0xfd53; goto top;",
2316 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
2318 "WLAT (R[n], DSP_R (m));",
2321 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
2323 "WWAT (R[n], DSP_R (m) >> 16);",
2324 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2327 " iword &= 0xfd53; goto top;",
2331 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
2333 "WLAT (R[n], DSP_R (m));",
2334 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2337 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
2339 "WWAT (R[n], DSP_R (m) >> 16);",
2340 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2343 " iword &= 0xfd53; goto top;",
2347 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
2349 "WLAT (R[n], DSP_R (m));",
2350 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2353 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
2355 "DSP_R (m) = RSWAT (R[n]) << 16;",
2358 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
2360 "DSP_R (m) = RSWAT (R[n]) << 16;",
2361 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2364 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
2366 "DSP_R (m) = RSWAT (R[n]) << 16;",
2367 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2370 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
2372 "WWAT (R[n], DSP_R (m) >> 16);",
2375 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
2377 "WWAT (R[n], DSP_R (m) >> 16);",
2378 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2381 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
2383 "WWAT (R[n], DSP_R (m) >> 16);",
2384 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2387 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
2389 "DSP_R (m) = RLAT (R[n]);",
2392 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
2394 "DSP_R (m) = RLAT (R[n]);",
2395 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2398 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
2400 "DSP_R (m) = RLAT (R[n]);",
2401 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2404 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
2406 "WLAT (R[n], DSP_R (m));",
2409 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
2411 "WLAT (R[n], DSP_R (m));",
2412 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2415 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
2417 "WLAT (R[n], DSP_R (m));",
2418 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2421 { "", "", "nopx nopy", "1111000000000000",
2426 { "", "", "ppi", "1111100000000000",
2428 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
2429 "ppi_insn (RIAT (nip));",
2430 "SET_NIP (nip + 2);",
2431 "iword &= 0xf7ff; goto top;",
2438 static op ppi_tab
[] =
2440 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
2442 "int Sz = DSP_R (z) & 0xffff0000;",
2446 "else if (i >= 128 - 16)",
2447 " res = (unsigned) Sz >> (128 - i); /* no sign extension */",
2450 " RAISE_EXCEPTION (SIGILL);",
2453 "res &= 0xffff0000;",
2458 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
2460 "int Sz = DSP_R (z);",
2461 "int Sz_grd = GET_DSP_GRD (z);",
2473 " res_grd = Sz_grd << i | (unsigned) Sz >> (32 - i);",
2475 " res_grd = SEXT (res_grd);",
2476 " carry = res_grd & 1;",
2478 "else if (i >= 96)",
2483 " res_grd = SIGN32 (Sz_grd);",
2488 " res = Sz >> i | Sz_grd << (32 - i);",
2489 " res_grd = Sz_grd >> i;",
2491 " carry = Sz >> (i - 1) & 1;",
2495 " RAISE_EXCEPTION (SIGILL);",
2498 "COMPUTE_OVERFLOW;",
2499 "greater_equal = 0;",
2502 { "","", "pmuls Se,Sf,Dg", "0100eeff0000gg00",
2504 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2505 "if (res == 0x80000000)",
2506 " res = 0x7fffffff;",
2508 "DSP_GRD (g) = SIGN32 (res);",
2512 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
2514 "int Sx = DSP_R (x);",
2515 "int Sx_grd = GET_DSP_GRD (x);",
2516 "int Sy = DSP_R (y);",
2517 "int Sy_grd = SIGN32 (Sy);",
2519 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2520 "if (res == 0x80000000)",
2521 " res = 0x7fffffff;",
2523 "DSP_GRD (g) = SIGN32 (res);",
2527 "carry = (unsigned) res > (unsigned) Sx;",
2528 "res_grd = Sx_grd - Sy_grd - carry;",
2529 "COMPUTE_OVERFLOW;",
2533 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
2535 "int Sx = DSP_R (x);",
2536 "int Sx_grd = GET_DSP_GRD (x);",
2537 "int Sy = DSP_R (y);",
2538 "int Sy_grd = SIGN32 (Sy);",
2540 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2541 "if (res == 0x80000000)",
2542 " res = 0x7fffffff;",
2544 "DSP_GRD (g) = SIGN32 (res);",
2548 "carry = (unsigned) res < (unsigned) Sx;",
2549 "res_grd = Sx_grd + Sy_grd + carry;",
2550 "COMPUTE_OVERFLOW;",
2553 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
2555 "int Sx = DSP_R (x);",
2556 "int Sx_grd = GET_DSP_GRD (x);",
2557 "int Sy = DSP_R (y);",
2558 "int Sy_grd = SIGN32 (Sy);",
2560 "res = Sx - Sy - (DSR & 1);",
2561 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
2562 "res_grd = Sx_grd + Sy_grd + carry;",
2563 "COMPUTE_OVERFLOW;",
2566 "if (res || res_grd)\n",
2567 " DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n",
2569 " DSR |= DSR_MASK_Z | overflow;\n",
2574 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
2576 "int Sx = DSP_R (x);",
2577 "int Sx_grd = GET_DSP_GRD (x);",
2578 "int Sy = DSP_R (y);",
2579 "int Sy_grd = SIGN32 (Sy);",
2581 "res = Sx + Sy + (DSR & 1);",
2582 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
2583 "res_grd = Sx_grd + Sy_grd + carry;",
2584 "COMPUTE_OVERFLOW;",
2587 "if (res || res_grd)\n",
2588 " DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n",
2590 " DSR |= DSR_MASK_Z | overflow;\n",
2595 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
2597 "int Sx = DSP_R (x);",
2598 "int Sx_grd = GET_DSP_GRD (x);",
2599 "int Sy = DSP_R (y);",
2600 "int Sy_grd = SIGN32 (Sy);",
2602 "z = 17; /* Ignore result. */",
2604 "carry = (unsigned) res > (unsigned) Sx;",
2605 "res_grd = Sx_grd - Sy_grd - carry;",
2606 "COMPUTE_OVERFLOW;",
2610 { "","", "pwsb Sx,Sy,Dz", "10100100....zzzz",
2615 { "","", "pwad Sx,Sy,Dz", "10110100....zzzz",
2620 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
2622 "/* FIXME: duplicate code pabs. */",
2624 "res_grd = GET_DSP_GRD (x);",
2630 " carry = (res != 0); /* The manual has a bug here. */",
2631 " res_grd = -res_grd - carry;",
2633 "COMPUTE_OVERFLOW;",
2634 "/* ??? The re-computing of overflow after",
2635 " saturation processing is specific to pabs. */",
2636 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2640 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2643 "res_grd = GET_DSP_GRD (x);",
2649 " carry = (res != 0); /* The manual has a bug here. */",
2650 " res_grd = -res_grd - carry;",
2652 "COMPUTE_OVERFLOW;",
2653 "/* ??? The re-computing of overflow after",
2654 " saturation processing is specific to pabs. */",
2655 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2660 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2662 "/* FIXME: duplicate code prnd. */",
2663 "int Sx = DSP_R (x);",
2664 "int Sx_grd = GET_DSP_GRD (x);",
2666 "res = (Sx + 0x8000) & 0xffff0000;",
2667 "carry = (unsigned) res < (unsigned) Sx;",
2668 "res_grd = Sx_grd + carry;",
2669 "COMPUTE_OVERFLOW;",
2673 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2675 "int Sx = DSP_R (x);",
2676 "int Sx_grd = GET_DSP_GRD (x);",
2678 "res = (Sx + 0x8000) & 0xffff0000;",
2679 "carry = (unsigned) res < (unsigned) Sx;",
2680 "res_grd = Sx_grd + carry;",
2681 "COMPUTE_OVERFLOW;",
2686 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2688 "/* FIXME: duplicate code pabs. */",
2692 "greater_equal = DSR_MASK_G;",
2702 " res = 0x7fffffff;",
2705 " overflow = DSR_MASK_V;",
2706 " greater_equal = 0;",
2712 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2717 "greater_equal = DSR_MASK_G;",
2727 " res = 0x7fffffff;",
2730 " overflow = DSR_MASK_V;",
2731 " greater_equal = 0;",
2737 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2739 "/* FIXME: duplicate code prnd. */",
2740 "int Sy = DSP_R (y);",
2741 "int Sy_grd = SIGN32 (Sy);",
2743 "res = (Sy + 0x8000) & 0xffff0000;",
2744 "carry = (unsigned) res < (unsigned) Sy;",
2745 "res_grd = Sy_grd + carry;",
2746 "COMPUTE_OVERFLOW;",
2750 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2752 "int Sy = DSP_R (y);",
2753 "int Sy_grd = SIGN32 (Sy);",
2755 "res = (Sy + 0x8000) & 0xffff0000;",
2756 "carry = (unsigned) res < (unsigned) Sy;",
2757 "res_grd = Sy_grd + carry;",
2758 "COMPUTE_OVERFLOW;",
2762 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2764 "int Sx = DSP_R (x) & 0xffff0000;",
2765 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2769 "else if (Sy >= 128 - 16)",
2770 " res = (unsigned) Sx >> (128 - Sy); /* no sign extension */",
2773 " RAISE_EXCEPTION (SIGILL);",
2776 "goto cond_logical;",
2779 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2781 "int Sx = DSP_R (x);",
2782 "int Sx_grd = GET_DSP_GRD (x);",
2783 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2795 " res_grd = Sx_grd << Sy | (unsigned) Sx >> (32 - Sy);",
2797 " res_grd = SEXT (res_grd);",
2798 " carry = res_grd & 1;",
2800 "else if (Sy >= 96)",
2805 " res_grd = SIGN32 (Sx_grd);",
2810 " res = Sx >> Sy | Sx_grd << (32 - Sy);",
2811 " res_grd = Sx_grd >> Sy;",
2813 " carry = Sx >> (Sy - 1) & 1;",
2817 " RAISE_EXCEPTION (SIGILL);",
2820 "COMPUTE_OVERFLOW;",
2821 "greater_equal = 0;",
2824 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2826 "int Sx = DSP_R (x);",
2827 "int Sx_grd = GET_DSP_GRD (x);",
2828 "int Sy = DSP_R (y);",
2829 "int Sy_grd = SIGN32 (Sy);",
2832 "carry = (unsigned) res > (unsigned) Sx;",
2833 "res_grd = Sx_grd - Sy_grd - carry;",
2834 "COMPUTE_OVERFLOW;",
2838 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2840 "int Sx = DSP_R (x);",
2841 "int Sx_grd = GET_DSP_GRD (x);",
2842 "int Sy = DSP_R (y);",
2843 "int Sy_grd = SIGN32 (Sy);",
2846 "carry = (unsigned) res > (unsigned) Sy;",
2847 "res_grd = Sy_grd - Sx_grd - carry;",
2848 "COMPUTE_OVERFLOW;",
2852 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2854 "int Sx = DSP_R (x);",
2855 "int Sx_grd = GET_DSP_GRD (x);",
2856 "int Sy = DSP_R (y);",
2857 "int Sy_grd = SIGN32 (Sy);",
2860 "carry = (unsigned) res < (unsigned) Sx;",
2861 "res_grd = Sx_grd + Sy_grd + carry;",
2862 "COMPUTE_OVERFLOW;",
2866 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2868 "res = DSP_R (x) & DSP_R (y);",
2870 "res &= 0xffff0000;",
2872 "if (iword & 0x200)\n",
2873 " goto assign_z;\n",
2877 "greater_equal = 0;",
2880 " DSR |= res >> 26 & DSR_MASK_N;\n",
2882 " DSR |= DSR_MASK_Z;\n",
2883 "goto assign_dc;\n",
2886 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2888 "res = DSP_R (x) ^ DSP_R (y);",
2889 "goto cond_logical;",
2892 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2894 "res = DSP_R (x) | DSP_R (y);",
2895 "goto cond_logical;",
2898 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2900 "int Sx = DSP_R (x);",
2901 "int Sx_grd = GET_DSP_GRD (x);",
2903 "res = Sx - 0x10000;",
2904 "carry = Sx < (INT_MIN + 0x10000);",
2905 "res_grd = Sx_grd - carry;",
2906 "COMPUTE_OVERFLOW;",
2908 "res &= 0xffff0000;",
2911 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2913 "int Sx = DSP_R (x);",
2914 "int Sx_grd = GET_DSP_GRD (x);",
2916 "res = Sx + 0x10000;",
2917 "carry = Sx > (INT_MAX - 0x10000);",
2918 "res_grd = Sx_grd + carry;",
2919 "COMPUTE_OVERFLOW;",
2921 "res &= 0xffff0000;",
2924 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2926 "int Sy = DSP_R (y);",
2927 "int Sy_grd = SIGN32 (Sy);",
2929 "res = Sy - 0x10000;",
2930 "carry = Sy < (INT_MIN + 0x10000);",
2931 "res_grd = Sy_grd - carry;",
2932 "COMPUTE_OVERFLOW;",
2934 "res &= 0xffff0000;",
2937 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2939 "int Sy = DSP_R (y);",
2940 "int Sy_grd = SIGN32 (Sy);",
2942 "res = Sy + 0x10000;",
2943 "carry = Sy > (INT_MAX - 0x10000);",
2944 "res_grd = Sy_grd + carry;",
2945 "COMPUTE_OVERFLOW;",
2947 "res &= 0xffff0000;",
2950 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2956 "greater_equal = 1;",
2959 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2961 "/* Do multiply. */",
2962 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2963 "if (res == 0x80000000)",
2964 " res = 0x7fffffff;",
2966 "DSP_GRD (g) = SIGN32 (res);",
2967 "/* FIXME: update DSR based on results of multiply! */",
2976 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2978 "unsigned Sx = DSP_R (x);",
2979 "int Sx_grd = GET_DSP_GRD (x);",
2984 " Sx_grd = ~Sx_grd;",
2998 " if (Sx & ((unsigned)~0 << i))",
3006 "res_grd = SIGN32 (res);",
3012 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
3014 "unsigned Sy = DSP_R (y);",
3023 " if (Sy & ((unsigned)~0 << i))",
3031 "res_grd = SIGN32 (res);",
3037 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
3039 "int Sx = DSP_R (x);",
3040 "int Sx_grd = GET_DSP_GRD (x);",
3043 "carry = res != 0;",
3044 "res_grd = 0 - Sx_grd - carry;",
3045 "COMPUTE_OVERFLOW;",
3049 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
3052 "res_grd = GET_DSP_GRD (x);",
3054 "COMPUTE_OVERFLOW;",
3058 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
3060 "int Sy = DSP_R (y);",
3061 "int Sy_grd = SIGN32 (Sy);",
3064 "carry = res != 0;",
3065 "res_grd = 0 - Sy_grd - carry;",
3066 "COMPUTE_OVERFLOW;",
3070 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
3073 "res_grd = SIGN32 (res);",
3075 "COMPUTE_OVERFLOW;",
3079 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
3082 "res_grd = SIGN32 (res);",
3086 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
3089 "res_grd = SIGN32 (res);",
3093 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
3095 "if (0xa05f >> z & 1)",
3096 " RAISE_EXCEPTION (SIGILL);",
3098 " MACH = DSP_R (z);",
3102 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
3104 "if (0xa05f >> z & 1)",
3105 " RAISE_EXCEPTION (SIGILL);",
3107 " MACL = DSP_R (z);",
3112 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
3114 "int Sx = DSP_R (x);",
3116 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
3117 "res_grd = GET_DSP_GRD (x);",
3120 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
3124 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
3126 "int Sy = DSP_R (y);",
3128 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
3129 "res_grd = SIGN32 (Sy);",
3132 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
3140 qfunc (const void *va
, const void *vb
)
3148 memcpy (bufa
, a
->code
, 4);
3149 memcpy (bufa
+ 4, a
->code
+ 12, 4);
3152 memcpy (bufb
, b
->code
, 4);
3153 memcpy (bufb
+ 4, b
->code
+ 12, 4);
3155 diff
= strcmp (bufa
, bufb
);
3156 /* Stabilize the sort, so that later entries can override more general
3157 preceding entries. */
3158 return diff
? diff
: a
- b
;
3172 qsort (tab
, len
, sizeof (*p
), qfunc
);
3180 for (p
= tab
; p
->name
; p
++)
3182 printf ("%s %-30s\n", p
->code
, p
->name
);
3186 static unsigned short table
[1 << 16];
3188 static int warn_conflicts
= 0;
3191 conflict_warn (int val
, int i
)
3196 fprintf (stderr
, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
3197 val
, i
, table
[val
]);
3199 for (ix
= ARRAY_SIZE (tab
); ix
>= 0; ix
--)
3200 if (tab
[ix
].index
== i
|| tab
[ix
].index
== j
)
3202 key
= ((tab
[ix
].code
[0] - '0') << 3) +
3203 ((tab
[ix
].code
[1] - '0') << 2) +
3204 ((tab
[ix
].code
[2] - '0') << 1) +
3205 ((tab
[ix
].code
[3] - '0'));
3207 if (val
>> 12 == key
)
3208 fprintf (stderr
, " %s -- %s\n", tab
[ix
].code
, tab
[ix
].name
);
3211 for (ix
= ARRAY_SIZE (movsxy_tab
); ix
>= 0; ix
--)
3212 if (movsxy_tab
[ix
].index
== i
|| movsxy_tab
[ix
].index
== j
)
3214 key
= ((movsxy_tab
[ix
].code
[0] - '0') << 3) +
3215 ((movsxy_tab
[ix
].code
[1] - '0') << 2) +
3216 ((movsxy_tab
[ix
].code
[2] - '0') << 1) +
3217 ((movsxy_tab
[ix
].code
[3] - '0'));
3219 if (val
>> 12 == key
)
3220 fprintf (stderr
, " %s -- %s\n",
3221 movsxy_tab
[ix
].code
, movsxy_tab
[ix
].name
);
3224 for (ix
= ARRAY_SIZE (ppi_tab
); ix
>= 0; ix
--)
3225 if (ppi_tab
[ix
].index
== i
|| ppi_tab
[ix
].index
== j
)
3227 key
= ((ppi_tab
[ix
].code
[0] - '0') << 3) +
3228 ((ppi_tab
[ix
].code
[1] - '0') << 2) +
3229 ((ppi_tab
[ix
].code
[2] - '0') << 1) +
3230 ((ppi_tab
[ix
].code
[3] - '0'));
3232 if (val
>> 12 == key
)
3233 fprintf (stderr
, " %s -- %s\n",
3234 ppi_tab
[ix
].code
, ppi_tab
[ix
].name
);
3238 /* Take an opcode, expand all varying fields in it out and fill all the
3239 right entries in 'table' with the opcode index. */
3242 expand_opcode (int val
, int i
, const char *s
)
3246 if (warn_conflicts
&& table
[val
] != 0)
3247 conflict_warn (val
, i
);
3257 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
3261 /* Consume an arbitrary number of ones and zeros. */
3263 j
= (j
<< 1) + (s
[m
++] - '0');
3264 } while (s
[m
] == '0' || s
[m
] == '1');
3265 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
3267 case 'N': /* NN -- four-way fork */
3268 for (j
= 0; j
< 4; j
++)
3269 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3271 case 'x': /* xx or xy -- two-way or four-way fork */
3272 for (j
= 0; j
< 4; j
+= (s
[1] == 'x' ? 2 : 1))
3273 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3275 case 'y': /* yy or yx -- two-way or four-way fork */
3276 for (j
= 0; j
< (s
[1] == 'x' ? 4 : 2); j
++)
3277 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3279 case '?': /* Seven-way "wildcard" fork for movxy */
3280 expand_opcode ((val
<< 2), i
, s
+ 2);
3281 for (j
= 1; j
< 4; j
++)
3283 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3284 expand_opcode ((val
<< 2) | (j
+ 16), i
, s
+ 2);
3287 case 'i': /* eg. "i8*1" */
3288 case '.': /* "...." is a wildcard */
3291 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
3292 for (j
= 0; j
< 16; j
++)
3293 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3296 /* eeee -- even numbered register:
3298 for (j
= 0; j
< 15; j
+= 2)
3299 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3302 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
3303 MMMM -- 10-way fork */
3304 expand_opcode ((val
<< 4) | 5, i
, s
+ 4);
3305 for (j
= 7; j
< 16; j
++)
3306 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3310 GGGG -- two-way fork */
3311 for (j
= 13; j
<= 15; j
+=2)
3312 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3315 /* ssss -- 10-way fork */
3316 /* System registers mach, macl, pr: */
3317 for (j
= 0; j
< 3; j
++)
3318 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3319 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
3320 for (j
= 5; j
< 12; j
++)
3321 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3324 /* XX/XY -- 2/4 way fork. */
3325 for (j
= 0; j
< 4; j
+= (s
[1] == 'X' ? 2 : 1))
3326 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3329 /* aa/ax -- 2/4 way fork. */
3330 for (j
= 0; j
< 4; j
+= (s
[1] == 'a' ? 2 : 1))
3331 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3334 /* YY/YX -- 2/4 way fork. */
3335 for (j
= 0; j
< (s
[1] == 'Y' ? 2 : 4); j
+= 1)
3336 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3339 /* AA/AY: 2/4 way fork. */
3340 for (j
= 0; j
< (s
[1] == 'A' ? 2 : 4); j
+= 1)
3341 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3344 /* vv(VV) -- 4(16) way fork. */
3345 /* Vector register fv0/4/8/12. */
3348 /* 2 vector registers. */
3349 for (j
= 0; j
< 15; j
++)
3350 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
3354 /* 1 vector register. */
3355 for (j
= 0; j
< 4; j
+= 1)
3356 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
3363 /* Print the jump table used to index an opcode into a switch
3367 dumptable (const char *name
, int size
, int start
)
3374 printf ("unsigned short %s[%d] = {\n", name
, size
);
3375 while (i
< start
+ size
)
3379 printf ("/* 0x%x */\n", i
);
3386 printf ("%2d", table
[i
+ j
+ k
]);
3404 static int index
= 1;
3407 for (; p
->name
; p
++)
3410 expand_opcode (0, p
->index
, p
->code
);
3414 /* Table already contains all the switch case tags for 16-bit opcode double
3415 data transfer (ddt) insns, and the switch case tag for processing parallel
3416 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
3417 latter tag to represent all combinations of ppi with ddt. */
3419 expand_ppi_movxy (void)
3423 for (i
= 0xf000; i
< 0xf400; i
++)
3425 table
[i
+ 0x800] = table
[0xf800];
3429 gensim_caselist (op
*p
)
3431 for (; p
->name
; p
++)
3437 const char *s
= p
->code
;
3439 printf (" /* %s %s */\n", p
->name
, p
->code
);
3440 printf (" case %d:\n", p
->index
);
3448 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
3453 /* Wildcard expansion, nothing to do here. */
3457 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
3461 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
3473 printf (" int n = (iword >> 8) & 0xf;\n");
3478 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
3482 if (s
[1] == 'y') /* xy */
3484 printf (" int n = (iword & 3) ?\n");
3485 printf (" ((iword >> 9) & 1) + 4 :\n");
3486 printf (" REG_xy ((iword >> 8) & 3);\n");
3489 printf (" int n = ((iword >> 9) & 1) + 4;\n");
3494 if (s
[1] == 'x') /* yx */
3496 printf (" int n = (iword & 0xc) ?\n");
3497 printf (" ((iword >> 8) & 1) + 6 :\n");
3498 printf (" REG_yx ((iword >> 8) & 3);\n");
3501 printf (" int n = ((iword >> 8) & 1) + 6;\n");
3510 printf (" int m = (iword >> 4) & 0xf;\n");
3514 if (s
[1] == 'Y') /* XY */
3516 printf (" int m = (iword & 3) ?\n");
3517 printf (" ((iword >> 7) & 1) + 8 :\n");
3518 printf (" DSP_xy ((iword >> 6) & 3);\n");
3521 printf (" int m = ((iword >> 7) & 1) + 8;\n");
3525 if (s
[1] == 'x') /* ax */
3527 printf (" int m = (iword & 3) ?\n");
3528 printf (" 7 - ((iword >> 6) & 2) :\n");
3529 printf (" DSP_ax ((iword >> 6) & 3);\n");
3532 printf (" int m = 7 - ((iword >> 6) & 2);\n");
3536 if (s
[1] == 'X') /* YX */
3538 printf (" int m = (iword & 0xc) ?\n");
3539 printf (" ((iword >> 6) & 1) + 10 :\n");
3540 printf (" DSP_yx ((iword >> 6) & 3);\n");
3543 printf (" int m = ((iword >> 6) & 1) + 10;\n");
3547 if (s
[1] == 'Y') /* AY */
3549 printf (" int m = (iword & 0xc) ?\n");
3550 printf (" 7 - ((iword >> 5) & 2) :\n");
3551 printf (" DSP_ay ((iword >> 6) & 3);\n");
3554 printf (" int m = 7 - ((iword >> 5) & 2);\n");
3559 printf (" int i = (iword & 0x");
3565 "gensim_caselist: Unknown char '%c' in %s\n",
3586 "gensim_caselist: Unknown char '%c' in %s\n",
3590 case '.': /* eg. "i12." */
3607 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3608 sextbit
- 1, sextbit
- 1);
3612 printf (" TB (m,n);\n");
3614 printf (" TL (m);\n");
3616 printf (" TL (n);\n");
3621 for (r
= p
->refs
; *r
; r
++)
3623 if (*r
== 'f') printf (" CREF (15);\n");
3627 printf (" int i = n;\n");
3629 printf (" CREF (i);\n");
3630 printf (" } while (i-- > 0);\n");
3636 printf (" int i = n;\n");
3638 printf (" CREF (i);\n");
3639 printf (" } while (i++ < 14);\n");
3642 if (*r
== '0') printf (" CREF (0);\n");
3643 if (*r
== '8') printf (" CREF (8);\n");
3644 if (*r
== '9') printf (" CREF (9);\n");
3645 if (*r
== 'n') printf (" CREF (n);\n");
3646 if (*r
== 'm') printf (" CREF (m);\n");
3651 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3655 printf (" %s\n", p
->stuff
[j
]);
3663 for (r
= p
->defs
; *r
; r
++)
3665 if (*r
== 'f') printf (" CDEF (15);\n");
3669 printf (" int i = n;\n");
3671 printf (" CDEF (i);\n");
3672 printf (" } while (i-- > 0);\n");
3678 printf (" int i = n;\n");
3680 printf (" CDEF (i);\n");
3681 printf (" } while (i++ < 14);\n");
3684 if (*r
== '0') printf (" CDEF (0);\n");
3685 if (*r
== 'n') printf (" CDEF (n);\n");
3686 if (*r
== 'm') printf (" CDEF (m);\n");
3690 printf (" break;\n");
3699 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3700 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3701 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3702 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3703 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3704 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3705 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3706 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3707 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3708 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3709 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3710 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3711 printf (" switch (jump_table[iword]) {\n");
3713 gensim_caselist (tab
);
3714 gensim_caselist (movsxy_tab
);
3716 printf (" default:\n");
3718 printf (" RAISE_EXCEPTION (SIGILL);\n");
3729 for (p
= tab
; p
->name
; p
++)
3731 const char *s
= p
->name
;
3732 printf ("#define OPC_");
3735 printf ("%c", tolower (*s
));
3744 printf (" %d\n",p
->index
);
3748 static int ppi_index
;
3750 /* Take a ppi code, expand all varying fields in it and fill all the
3751 right entries in 'table' with the opcode index.
3752 NOTE: tail recursion optimization removed for simplicity. */
3755 expand_ppi_code (int val
, int i
, const char *s
)
3762 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n", s
[0]);
3767 if (warn_conflicts
&& table
[val
] != 0)
3768 conflict_warn (val
, i
);
3770 /* The last four bits are disregarded for the switch table. */
3774 /* Four-bit expansion. */
3775 for (j
= 0; j
< 16; j
++)
3776 expand_ppi_code ((val
<< 4) + j
, i
, s
+ 4);
3780 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3783 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3788 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3789 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3792 expand_ppi_code ((val
<< 2) + 1, ppi_index
++, s
+ 2);
3793 expand_ppi_code ((val
<< 2) + 2, i
, s
+ 2);
3794 expand_ppi_code ((val
<< 2) + 3, i
, s
+ 2);
3800 ppi_filltable (void)
3805 for (p
= ppi_tab
; p
->name
; p
++)
3807 p
->index
= ppi_index
++;
3808 expand_ppi_code (0, p
->index
, p
->code
);
3817 printf ("#define DSR_MASK_G 0x80\n");
3818 printf ("#define DSR_MASK_Z 0x40\n");
3819 printf ("#define DSR_MASK_N 0x20\n");
3820 printf ("#define DSR_MASK_V 0x10\n");
3822 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3823 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;\\\n");
3824 printf (" if (overflow && S) \\\n");
3826 printf (" if (res_grd & 0x80) \\\n");
3828 printf (" res = 0x80000000;\\\n");
3829 printf (" res_grd |= 0xff;\\\n");
3831 printf (" else \\\n");
3833 printf (" res = 0x7fffffff;\\\n");
3834 printf (" res_grd &= ~0xff;\\\n");
3836 printf (" overflow = 0;\\\n");
3838 printf ("} while (0)\n");
3840 printf ("#define ADD_SUB_GE \\\n");
3841 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3843 printf ("static void\n");
3844 printf ("ppi_insn (int iword)\n");
3846 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3847 printf (" static char const e_tab[] = { 8, 9, 10, 5};\n");
3848 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3849 printf (" static char const f_tab[] = {10, 11, 8, 5};\n");
3850 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3851 printf (" static char const x_tab[] = { 8, 9, 7, 5};\n");
3852 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3853 printf (" static char const y_tab[] = {10, 11, 12, 14};\n");
3854 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3855 printf (" static char const g_tab[] = {12, 14, 7, 5};\n");
3856 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3857 printf (" static char const u_tab[] = { 8, 10, 7, 5};\n");
3859 printf (" int z;\n");
3860 printf (" int res, res_grd;\n");
3861 printf (" int carry, overflow, greater_equal;\n");
3863 printf (" switch (ppi_table[iword >> 4]) {\n");
3865 for (; p
->name
; p
++)
3870 const char *s
= p
->code
;
3872 printf (" /* %s %s */\n", p
->name
, p
->code
);
3873 printf (" case %d:\n", p
->index
);
3876 for (shift
= 16; *s
; )
3881 printf (" int i = (iword >> 4) & 0x7f;\n");
3891 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3897 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3898 printf ("\treturn;\n");
3899 printf (" ATTRIBUTE_FALLTHROUGH;\n");
3901 printf (" case %d:\n", p
->index
+ 1);
3913 printf (" z = iword & 0xf;\n");
3921 else if (havedecl
== 2)
3923 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3930 (havedecl
== 2 ? " " : ""),
3940 printf (" if (iword & 0x200)\n");
3941 printf (" goto assign_z;\n");
3943 printf (" break;\n");
3947 printf (" default:\n");
3949 printf (" RAISE_EXCEPTION (SIGILL);\n");
3950 printf (" return;\n");
3953 printf (" DSR &= ~0xf1;\n");
3954 printf (" if (res || res_grd)\n");
3955 printf (" DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n");
3957 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3958 printf (" assign_dc:\n");
3959 printf (" switch (DSR >> 1 & 7)\n");
3961 printf (" case 0: /* Carry Mode */\n");
3962 printf (" DSR |= carry;\n");
3963 printf (" break;\n");
3964 printf (" case 1: /* Negative Value Mode */\n");
3965 printf (" DSR |= res_grd >> 7 & 1;\n");
3966 printf (" break;\n");
3967 printf (" case 2: /* Zero Value Mode */\n");
3968 printf (" DSR |= DSR >> 6 & 1;\n");
3969 printf (" break;\n");
3970 printf (" case 3: /* Overflow mode */\n");
3971 printf (" DSR |= overflow >> 4;\n");
3972 printf (" break;\n");
3973 printf (" case 4: /* Signed Greater Than Mode */\n");
3974 printf (" DSR |= DSR >> 7 & 1;\n");
3975 printf (" break;\n");
3976 printf (" case 5: /* Signed Greater Than Or Equal Mode */\n");
3977 printf (" DSR |= greater_equal >> 7;\n");
3978 printf (" break;\n");
3980 printf (" assign_z:\n");
3981 printf (" if (0xa05f >> z & 1)\n");
3983 printf (" RAISE_EXCEPTION (SIGILL);\n");
3984 printf (" return;\n");
3986 printf (" DSP_R (z) = res;\n");
3987 printf (" DSP_GRD (z) = res_grd;\n");
3992 main (int ac
, char *av
[])
3994 /* Verify the table before anything else. */
3997 for (p
= tab
; p
->name
; p
++)
3999 /* Check that the code field contains 16 bits. */
4000 if (strlen (p
->code
) != 16)
4002 fprintf (stderr
, "Code `%s' length wrong (%zu) for `%s'\n",
4003 p
->code
, strlen (p
->code
), p
->name
);
4009 /* Now generate the requested data. */
4012 if (ac
> 2 && strcmp (av
[2], "-w") == 0)
4016 if (strcmp (av
[1], "-t") == 0)
4020 else if (strcmp (av
[1], "-d") == 0)
4024 else if (strcmp (av
[1], "-s") == 0)
4027 dumptable ("sh_jump_table", 1 << 16, 0);
4029 memset (table
, 0, sizeof table
);
4030 filltable (movsxy_tab
);
4031 expand_ppi_movxy ();
4032 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
4034 memset (table
, 0, sizeof table
);
4036 dumptable ("ppi_table", 1 << 12, 0);
4038 else if (strcmp (av
[1], "-x") == 0)
4041 filltable (movsxy_tab
);
4044 else if (strcmp (av
[1], "-p") == 0)
4051 fprintf (stderr
, "Opcode table generation no longer supported.\n");