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
35 #define MAX_NR_STUFF 42
43 char *stuff[MAX_NR_STUFF];
51 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
54 " UNDEF(n); /* see #ifdef PARANOID */",
58 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
62 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
64 "SET_SR_T (ult < R[n]);",
66 "SET_SR_T (T || (R[n] < ult));",
69 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
71 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
75 { "0", "0", "and #<imm>,R0", "11001001i8*1....",
78 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
81 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
83 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
86 { "", "", "bf <bdisp8>", "10001011i8p1....",
87 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
89 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
97 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
99 " Delay_Slot (PC + 2);",
103 { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
104 "/* 32-bit logical bit-manipulation instructions. */",
105 "int word2 = RIAT (nip);",
106 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
107 "i >>= 4; /* BOGUS: Using only three bits of 'i'. */",
108 "/* MSB of 'i' must be zero. */",
110 " RAISE_EXCEPTION (SIGILL);",
112 "do_blog_insn (1 << i, (word2 & 0xfff) + R[n], ",
113 " (word2 >> 12) & 0xf, memory, maskb);",
114 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
116 { "", "", "bra <bdisp12>", "1010i12.........",
117 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
118 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
120 "Delay_Slot (PC + 2);",
123 { "", "n", "braf <REG_N>", "0000nnnn00100011",
124 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
125 "SET_NIP (PC + 4 + R[n]);",
127 "Delay_Slot (PC + 2);",
130 { "", "", "bsr <bdisp12>", "1011i12.........",
131 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
132 "PR = PH2T (PC + 4);",
133 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
135 "Delay_Slot (PC + 2);",
138 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
139 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
140 "PR = PH2T (PC) + 4;",
141 "SET_NIP (PC + 4 + R[n]);",
143 "Delay_Slot (PC + 2);",
146 { "", "", "bt <bdisp8>", "10001001i8p1....",
147 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
149 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
154 { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
155 "/* MSB of 'i' is true for load, false for store. */",
158 " R[m] |= (1 << i);",
160 " R[m] &= ~(1 << i);",
162 " SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
164 { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
165 "/* MSB of 'i' is true for set, false for clear. */",
167 " R[m] &= ~(1 << i);",
169 " R[m] |= (1 << (i - 8));",
171 { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
172 "if (R[n] < -128 || R[n] > 127) {",
177 " else if (R[n] < -128)",
181 { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
182 "if (R[n] < -32768 || R[n] > 32767) {",
185 " if (R[n] > 32767)",
187 " else if (R[n] < -32768)",
191 { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
192 "if (R[n] < -256 || R[n] > 255) {",
198 { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
199 "if (R[n] < -65536 || R[n] > 65535) {",
205 { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
206 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
208 " R[n] = 0x7fffffff;",
209 "else if (R0 == -1 && R[n] == 0x80000000)",
210 " R[n] = 0x7fffffff;",
214 { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
215 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
217 " R[n] = 0xffffffff;",
218 "else (unsigned int) R[n] = (unsigned int) R[n] / (unsigned int) R0;",
221 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
222 "R[n] = (R[n] * R0) & 0xffffffff;",
225 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
226 "int regn = (R[n] >> 2) & 0x1f;",
227 "int bankn = (R[n] >> 7) & 0x1ff;",
229 " regn = 19; /* FIXME what should happen? */",
230 "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
233 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
234 "int regn = (R[n] >> 2) & 0x1f;",
235 "int bankn = (R[n] >> 7) & 0x1ff;",
237 " regn = 19; /* FIXME what should happen? */",
238 "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
240 { "", "", "resbank", "0000000001011011",
242 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
243 /* FIXME: cdef all */
244 "if (BO) { /* Bank Overflow */",
245 /* FIXME: how do we know when to reset BO? */
246 " for (i = 0; i <= 14; i++) {",
247 " R[i] = RLAT (R[15]);",
251 " PR = RLAT (R[15]);",
254 " GBR = RLAT (R[15]);",
257 " MACH = RLAT (R[15]);",
260 " MACL = RLAT (R[15]);",
264 "else if (BANKN == 0) /* Bank Underflow */",
265 " RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */
267 " SET_BANKN (BANKN - 1);",
268 " for (i = 0; i <= 14; i++)",
269 " R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
270 " MACH = saved_state.asregs.regstack[BANKN].regs[15];",
271 " PR = saved_state.asregs.regstack[BANKN].regs[17];",
272 " GBR = saved_state.asregs.regstack[BANKN].regs[18];",
273 " MACL = saved_state.asregs.regstack[BANKN].regs[19];",
276 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
277 "/* Push Rn...R0 (if n==15, push pr and R14...R0). */",
282 " WLAT (R[15], PR);",
284 " WLAT (R[15], R[n]);",
285 "} while (n-- > 0);",
287 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
288 "/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */",
293 " PR = RLAT (R[15]);",
295 " R[i] = RLAT (R[15]);",
297 "} while (i++ < n);",
299 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
300 "/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */
306 " WLAT (R[15], PR);",
308 " WLAT (R[15], R[i]);",
309 "} while (i-- > n);",
311 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
312 "/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */
316 " PR = RLAT (R[15]);",
318 " R[n] = RLAT (R[15]);",
320 "} while (n++ < 15);",
322 { "", "", "nott", "0000000001101000",
323 "SET_SR_T (T == 0);",
326 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
327 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
329 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
331 " Delay_Slot (PC + 2);",
335 { "", "", "clrmac", "0000000000101000",
340 { "", "", "clrs", "0000000001001000",
344 { "", "", "clrt", "0000000000001000",
349 { "", "", "clrdmxy", "0000000010001000",
350 "saved_state.asregs.cregs.named.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
353 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
354 "SET_SR_T (R0 == SEXT (i));",
356 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
357 "SET_SR_T (R[n] == R[m]);",
359 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
360 "SET_SR_T (R[n] >= R[m]);",
362 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
363 "SET_SR_T (R[n] > R[m]);",
365 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
366 "SET_SR_T (UR[n] > UR[m]);",
368 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
369 "SET_SR_T (UR[n] >= UR[m]);",
371 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
372 "SET_SR_T (R[n] > 0);",
374 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
375 "SET_SR_T (R[n] >= 0);",
377 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
378 "ult = R[n] ^ R[m];",
379 "SET_SR_T (((ult & 0xff000000) == 0)",
380 " | ((ult & 0xff0000) == 0)",
381 " | ((ult & 0xff00) == 0)",
382 " | ((ult & 0xff) == 0));",
385 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
386 "SET_SR_Q ((R[n] & sbit) != 0);",
387 "SET_SR_M ((R[m] & sbit) != 0);",
388 "SET_SR_T (M != Q);",
391 { "", "", "div0u", "0000000000011001",
397 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
398 "div1 (&R0, m, n/*, T*/);",
401 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
402 "dmul (1/*signed*/, R[n], R[m]);",
405 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
406 "dmul (0/*unsigned*/, R[n], R[m]);",
409 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
411 "SET_SR_T (R[n] == 0);",
414 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
415 "R[n] = SEXT (R[m]);",
417 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
418 "R[n] = SEXTW (R[m]);",
421 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
422 "R[n] = (R[m] & 0xff);",
424 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
425 "R[n] = (R[m] & 0xffff);",
429 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
430 "FP_UNARY (n, fabs);",
431 "/* FIXME: FR (n) &= 0x7fffffff; */",
435 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
440 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
441 "FP_CMP (n, ==, m);",
444 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
449 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
450 "if (! FPSCR_PR || n & 1)",
451 " RAISE_EXCEPTION (SIGILL);",
465 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
466 "if (! FPSCR_PR || n & 1)",
467 " RAISE_EXCEPTION (SIGILL);",
481 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
483 "/* FIXME: check for DP and (n & 1) == 0? */",
487 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
489 " RAISE_EXCEPTION (SIGILL);",
493 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
494 " RAISE_EXCEPTION (SIGILL);",
495 " /* FIXME: check for nans and infinities. */",
496 " fsum += FR (v1+0) * FR (v2+0);",
497 " fsum += FR (v1+1) * FR (v2+1);",
498 " fsum += FR (v1+2) * FR (v2+2);",
499 " fsum += FR (v1+3) * FR (v2+3);",
500 " SET_FR (v1+3, fsum);",
505 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
506 "SET_FR (n, (float) 0.0);",
507 "/* FIXME: check for DP and (n & 1) == 0? */",
511 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
512 "SET_FR (n, (float) 1.0);",
513 "/* FIXME: check for DP and (n & 1) == 0? */",
517 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
528 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
531 " SET_DR (n, (double) FPUL);",
534 " SET_FR (n, (float) FPUL);",
539 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
540 "SET_FR (n, FR (m) * FR (0) + FR (n));",
541 "/* FIXME: check for DP and (n & 1) == 0? */",
545 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
548 " int ni = XD_TO_XF (n);",
549 " int mi = XD_TO_XF (m);",
550 " SET_XF (ni + 0, XF (mi + 0));",
551 " SET_XF (ni + 1, XF (mi + 1));",
555 " SET_FR (n, FR (m));",
559 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
568 " WLAT (R[n], FI (m));",
572 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
581 " SET_FI (n, RLAT (R[m]));",
585 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
586 "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
587 " and mov.bwl <REG_N>, @(disp12,<REG_M>)",
588 " and mov.bwl @(disp12,<REG_N>),<REG_M>",
589 " and movu.bw @(disp12,<REG_N>),<REG_M>. */",
590 "int word2 = RIAT (nip);",
591 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
592 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
594 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
597 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
607 " SET_FI (n, RLAT (R[m]));",
612 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
623 " WLAT (R[n], FI (m));",
627 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
631 " RDAT (R[0]+R[m], n);",
636 " SET_FI (n, RLAT (R[0] + R[m]));",
640 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
644 " WDAT (R[0]+R[n], m);",
649 " WLAT ((R[0]+R[n]), FI (m));",
654 See fmov instructions above for move to/from extended fp registers. */
657 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
662 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
667 { "", "", "fpchg", "1111011111111101",
668 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
672 { "", "", "frchg", "1111101111111101",
674 " RAISE_EXCEPTION (SIGILL);",
675 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
676 " RAISE_EXCEPTION (SIGILL);",
678 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
682 { "", "", "fsca", "1111eeee11111101",
684 " RAISE_EXCEPTION (SIGILL);",
685 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
686 " RAISE_EXCEPTION (SIGILL);",
689 " SET_FR (n, fsca_s (FPUL, &sin));",
690 " SET_FR (n+1, fsca_s (FPUL, &cos));",
695 { "", "", "fschg", "1111001111111101",
696 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
700 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
701 "FP_UNARY (n, sqrt);",
705 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
707 " RAISE_EXCEPTION (SIGILL);",
708 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
709 " RAISE_EXCEPTION (SIGILL);",
711 " SET_FR (n, fsrra_s (FR (n)));",
715 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
720 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
723 " if (DR (n) != DR (n)) /* NaN */",
724 " FPUL = 0x80000000;",
726 " FPUL = (int) DR (n);",
729 "if (FR (n) != FR (n)) /* NaN */",
730 " FPUL = 0x80000000;",
732 " FPUL = (int) FR (n);",
736 { "", "", "ftrv <FV_N>", "1111vv0111111101",
738 " RAISE_EXCEPTION (SIGILL);",
741 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
742 " RAISE_EXCEPTION (SIGILL);",
743 " /* FIXME not implemented. */",
744 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
749 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
759 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
760 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
761 "SET_NIP (PT2H (R[n]));",
763 "Delay_Slot (PC + 2);",
766 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
767 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
768 "PR = PH2T (PC + 4);",
770 " gotcall (PR, R[n]);",
771 "SET_NIP (PT2H (R[n]));",
773 "Delay_Slot (PC + 2);",
775 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
776 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
777 "PR = PH2T (PC + 2);",
779 " gotcall (PR, R[n]);",
780 "SET_NIP (PT2H (R[n]));",
782 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
783 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
784 "PR = PH2T (PC + 2);",
786 " gotcall (PR, i + TBR);",
787 "SET_NIP (PT2H (i + TBR));",
790 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
792 "/* FIXME: user mode */",
794 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
796 "/* FIXME: user mode */",
798 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
801 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
803 " DBR = R[n]; /* priv mode */",
805 " RAISE_EXCEPTION (SIGILL); /* user mode */",
807 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
809 " SGR = R[n]; /* priv mode */",
811 " RAISE_EXCEPTION (SIGILL); /* user mode */",
813 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
814 "if (SR_MD)", /* FIXME? */
815 " TBR = R[n]; /* priv mode */",
817 " RAISE_EXCEPTION (SIGILL); /* user mode */",
819 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
821 "CREG (m) = RLAT (R[n]);",
823 "/* FIXME: user mode */",
825 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
827 "SET_SR (RLAT (R[n]));",
829 "/* FIXME: user mode */",
831 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
833 "SET_MOD (RLAT (R[n]));",
836 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
840 " DBR = RLAT (R[n]);",
844 " RAISE_EXCEPTION (SIGILL); /* user mode */",
846 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
850 " SGR = RLAT (R[n]);",
854 " RAISE_EXCEPTION (SIGILL); /* user mode */",
858 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
859 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
861 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
862 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
866 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
868 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
869 "CHECK_INSN_PTR (insn_ptr);",
872 { "", "", "ldrc #<imm>", "10001010i8*1....",
874 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
875 "CHECK_INSN_PTR (insn_ptr);",
879 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
882 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
884 "SREG (m) = RLAT (R[n]);",
887 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
888 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
891 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
892 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
894 "SET_FPSCR (RLAT (R[n]));",
898 { "", "", "ldtlb", "0000000000111000",
899 "/* We don't implement cache or tlb, so this is a noop. */",
902 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
903 "macl (&R0, memory, n, m);",
906 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
907 "macw (&R0, memory, n, m, endianw);",
910 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
913 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
914 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
915 "R[n] = ((i << 24) >> 12) | RIAT (nip);",
916 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
918 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
919 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
920 "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
921 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
923 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
927 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
929 "R0 = RSBAT (i + GBR);",
932 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
934 "R0 = RSBAT (i + R[m]);",
937 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
939 "R[n] = RSBAT (R0 + R[m]);",
942 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
944 "R[n] = RSBAT (R[m]);",
948 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
951 "R0 = RSBAT (R[n]);",
954 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
956 "WBAT (R[n], R[m]);",
958 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
960 "WBAT (i + GBR, R0);",
962 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
964 "WBAT (i + R[m], R0);",
966 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
968 "WBAT (R[n] + R0, R[m]);",
970 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
973 "WBAT (R[n], R[m]);",
975 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
980 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
982 "R[n] = RSBAT (R[m]);",
986 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
988 "R0 = RLAT (i + GBR);",
991 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
993 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
996 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
998 "R[n] = RLAT (i + R[m]);",
1001 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1003 "R[n] = RLAT (R0 + R[m]);",
1006 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1008 "R[n] = RLAT (R[m]);",
1012 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1015 "R0 = RLAT (R[n]);",
1018 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1020 "R[n] = RLAT (R[m]);",
1023 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1025 "WLAT (i + GBR, R0);",
1027 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1029 "WLAT (i + R[n], R[m]);",
1031 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1033 "WLAT (R0 + R[n], R[m]);",
1035 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1038 "WLAT (R[n], R[m]);",
1040 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1045 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1047 "WLAT (R[n], R[m]);",
1050 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1052 "R0 = RSWAT (i + GBR);",
1055 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1057 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1060 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1062 "R0 = RSWAT (i + R[m]);",
1065 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1067 "R[n] = RSWAT (R0 + R[m]);",
1070 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1072 "R[n] = RSWAT (R[m]);",
1076 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1079 "R0 = RSWAT (R[n]);",
1082 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1084 "R[n] = RSWAT (R[m]);",
1087 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1089 "WWAT (i + GBR, R0);",
1091 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1093 "WWAT (i + R[m], R0);",
1095 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1097 "WWAT (R0 + R[n], R[m]);",
1099 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1102 "WWAT (R[n], R[m]);",
1104 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1109 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1111 "WWAT (R[n], R[m]);",
1114 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1115 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1118 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1119 "/* We don't simulate cache, so this insn is identical to mov. */",
1121 "WLAT (R[n], R[0]);",
1124 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1127 "/* if (T) R0 -> (Rn) */",
1129 " WLAT (R[n], R[0]);",
1134 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1138 "R[0] = RLAT (R[n]);",
1139 "/* if (interrupt/exception) 0 -> LDST */",
1140 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1143 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1146 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1149 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1151 "int e = target_little_endian ? 3 : 0;",
1153 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1154 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1157 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1159 "int e = target_little_endian ? 3 : 0;",
1161 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1162 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1166 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1167 "MACL = ((int) R[n]) * ((int) R[m]);",
1169 #if 0 /* FIXME: The above cast to int is not really portable.
1170 It should be replaced by a SEXT32 macro. */
1171 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1172 "MACL = R[n] * R[m];",
1176 /* muls.w - see muls */
1177 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1178 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1181 /* mulu.w - see mulu */
1182 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1183 "MACL = (((unsigned int) (unsigned short) R[n])",
1184 " * ((unsigned int) (unsigned short) R[m]));",
1187 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1191 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1193 "SET_SR_T (ult > 0);",
1194 "R[n] = ult - R[m];",
1195 "SET_SR_T (T || (R[n] > ult));",
1198 { "", "", "nop", "0000000000001001",
1202 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1207 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1208 "/* Except for the effect on the cache - which is not simulated -",
1209 " this is like a nop. */",
1212 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1213 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1214 "/* FIXME: Cache not implemented */",
1217 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1218 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1219 "/* FIXME: Cache not implemented */",
1222 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1223 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1224 "/* FIXME: Cache not implemented */",
1227 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1230 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1233 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1235 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1238 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1239 "/* Except for the effect on the cache - which is not simulated -",
1240 " this is like a nop. */",
1244 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1245 "/* Except for the effect on the cache - which is not simulated -",
1246 " this is like a nop. */",
1250 { "", "", "synco", "0000000010101011",
1251 "/* Except for the effect on the pipeline - which is not simulated -",
1252 " this is like a nop. */",
1255 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1257 "R[n] = (R[n] << 1) | T;",
1261 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1263 "R[n] = (UR[n] >> 1) | (T << 31);",
1267 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1268 "SET_SR_T (R[n] < 0);",
1273 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1274 "SET_SR_T (R[n] & 1);",
1275 "R[n] = UR[n] >> 1;",
1276 "R[n] |= (T << 31);",
1279 { "", "", "rte", "0000000000101011",
1283 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1285 "SET_SR (RLAT (R[15]) & 0x3f3);",
1287 "Delay_Slot (PC + 2);",
1289 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1291 "SET_NIP (PT2H (SPC));",
1293 "Delay_Slot (PC + 2);",
1297 { "", "", "rts", "0000000000001011",
1298 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1299 "SET_NIP (PT2H (PR));",
1301 "Delay_Slot (PC + 2);",
1303 { "", "", "rts/n", "0000000001101011",
1304 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1305 "SET_NIP (PT2H (PR));",
1307 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1308 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1311 "SET_NIP (PT2H (PR));",
1315 { "", "", "setdmx", "0000000010011000",
1316 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1317 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1321 { "", "", "setdmy", "0000000011001000",
1322 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1323 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1327 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1330 { "", "", "setrc #<imm>", "10000010i8*1....",
1331 /* It would be more realistic to let loop_start point to some static
1332 memory that contains an illegal opcode and then give a bus error when
1333 the loop is eventually encountered, but it seems not only simpler,
1334 but also more debugging-friendly to just catch the failure here. */
1335 "if (BUSERROR (RS | RE, maskw))",
1336 " RAISE_EXCEPTION (SIGILL);",
1339 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1340 " CHECK_INSN_PTR (insn_ptr);",
1344 { "", "", "sets", "0000000001011000",
1348 { "", "", "sett", "0000000000011000",
1352 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1353 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1356 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1357 "SET_SR_T (R[n] < 0);",
1361 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1362 "SET_SR_T (R[n] & 1);",
1363 "R[n] = R[n] >> 1;",
1366 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1367 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1370 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1371 "SET_SR_T (R[n] < 0);",
1375 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1378 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1381 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1385 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1386 "SET_SR_T (R[n] & 1);",
1387 "R[n] = UR[n] >> 1;",
1390 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1391 "R[n] = UR[n] >> 2;",
1393 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1394 "R[n] = UR[n] >> 8;",
1396 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1397 "R[n] = UR[n] >> 16;",
1400 { "", "", "sleep", "0000000000011011",
1401 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1404 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1408 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1410 " R[n] = SGR; /* priv mode */",
1412 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1414 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1416 " R[n] = DBR; /* priv mode */",
1418 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1420 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1421 "if (SR_MD)", /* FIXME? */
1422 " R[n] = TBR; /* priv mode */",
1424 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1426 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1429 "WLAT (R[n], CREG (m));",
1431 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1433 "{ /* priv mode */",
1436 " WLAT (R[n], SGR);",
1439 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1441 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1443 "{ /* priv mode */",
1446 " WLAT (R[n], DBR);",
1449 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1452 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1455 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1458 "WLAT (R[n], SREG (m));",
1461 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1465 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1467 "SET_SR_T (ult > R[n]);",
1468 "R[n] = ult - R[m];",
1469 "SET_SR_T (T || (R[n] > ult));",
1472 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1473 "ult = R[n] - R[m];",
1474 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1478 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1479 "R[n] = ((R[m] & 0xffff0000)",
1480 " | ((R[m] << 8) & 0xff00)",
1481 " | ((R[m] >> 8) & 0x00ff));",
1483 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1484 "R[n] = (((R[m] << 16) & 0xffff0000)",
1485 " | ((R[m] >> 16) & 0x00ffff));",
1488 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1490 "ult = RBAT (R[n]);",
1491 "SET_SR_T (ult == 0);",
1492 "WBAT (R[n],ult|0x80);",
1495 { "0", "", "trapa #<imm>", "11000011i8*1....",
1496 "long imm = 0xff & i;",
1497 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1498 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1499 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1504 " WLAT (R[15], GET_SR ());",
1506 " WLAT (R[15], PH2T (PC + 2));",
1508 "else if (!SR_BL) {",
1509 " SSR = GET_SR ();",
1510 " SPC = PH2T (PC + 2);",
1511 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1512 " /* FIXME: EXPEVT = 0x00000160; */",
1514 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1518 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1519 "SET_SR_T ((R[n] & R[m]) == 0);",
1521 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1522 "SET_SR_T ((R0 & i) == 0);",
1524 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1526 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1529 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1532 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1535 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1537 "ult = RBAT (GBR+R0);",
1539 "WBAT (GBR + R0, ult);",
1542 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1543 "R[n] = (((R[n] >> 16) & 0xffff)",
1544 " | ((R[m] << 16) & 0xffff0000));",
1548 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1549 "divl (0, R[n], R[m]);",
1551 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1552 "divl (0, R[n], R[m]);",
1560 /* If this is disabled, the simulator speeds up by about 12% on a
1561 450 MHz PIII - 9% with ACE_FAST.
1562 Maybe we should have separate simulator loops? */
1564 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1567 "DSP_R (m) = RSWAT (R[n]) << 16;",
1568 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1570 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1572 "DSP_R (m) = RSWAT (R[n]) << 16;",
1573 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1575 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1577 "DSP_R (m) = RSWAT (R[n]) << 16;",
1578 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1581 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1583 "DSP_R (m) = RSWAT (R[n]) << 16;",
1584 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1587 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1590 "DSP_R (m) = RSWAT (R[n]);",
1592 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1594 "DSP_R (m) = RSWAT (R[n]);",
1596 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1598 "DSP_R (m) = RSWAT (R[n]);",
1601 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1603 "DSP_R (m) = RSWAT (R[n]);",
1606 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1609 "WWAT (R[n], DSP_R (m) >> 16);",
1611 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1613 "WWAT (R[n], DSP_R (m) >> 16);",
1615 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1617 "WWAT (R[n], DSP_R (m) >> 16);",
1620 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1622 "WWAT (R[n], DSP_R (m) >> 16);",
1625 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1628 "WWAT (R[n], SEXT (DSP_R (m)));",
1630 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1632 "WWAT (R[n], SEXT (DSP_R (m)));",
1634 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1636 "WWAT (R[n], SEXT (DSP_R (m)));",
1639 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1641 "WWAT (R[n], SEXT (DSP_R (m)));",
1644 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1647 "DSP_R (m) = RLAT (R[n]);",
1648 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1650 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1652 "DSP_R (m) = RLAT (R[n]);",
1653 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1655 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1657 "DSP_R (m) = RLAT (R[n]);",
1658 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1661 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1663 "DSP_R (m) = RLAT (R[n]);",
1664 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1667 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1670 "WLAT (R[n], DSP_R (m));",
1672 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1674 "WLAT (R[n], DSP_R (m));",
1676 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1678 "WLAT (R[n], DSP_R (m));",
1681 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1683 "WLAT (R[n], DSP_R (m));",
1686 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1689 "WLAT (R[n], SEXT (DSP_R (m)));",
1691 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1693 "WLAT (R[n], SEXT (DSP_R (m)));",
1695 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1697 "WLAT (R[n], SEXT (DSP_R (m)));",
1700 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1702 "WLAT (R[n], SEXT (DSP_R (m)));",
1705 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1706 "DSP_R (m) = RSWAT (R[n]) << 16;",
1709 " iword &= 0xfd53; goto top;",
1712 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1713 "DSP_R (m) = RLAT (R[n]);",
1715 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1716 "DSP_R (m) = RSWAT (R[n]) << 16;",
1717 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1720 " iword &= 0xfd53; goto top;",
1723 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1724 "DSP_R (m) = RLAT (R[n]);",
1725 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1727 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1728 "DSP_R (m) = RSWAT (R[n]) << 16;",
1729 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1732 " iword &= 0xfd53; goto top;",
1735 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1736 "DSP_R (m) = RLAT (R[n]);",
1737 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1739 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1740 "WWAT (R[n], DSP_R (m) >> 16);",
1743 " iword &= 0xfd53; goto top;",
1746 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1747 "WLAT (R[n], DSP_R (m));",
1749 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1750 "WWAT (R[n], DSP_R (m) >> 16);",
1751 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1754 " iword &= 0xfd53; goto top;",
1757 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1758 "WLAT (R[n], DSP_R (m));",
1759 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1761 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1762 "WWAT (R[n], DSP_R (m) >> 16);",
1763 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1766 " iword &= 0xfd53; goto top;",
1769 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1770 "WLAT (R[n], DSP_R (m));",
1771 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1773 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1774 "DSP_R (m) = RSWAT (R[n]) << 16;",
1776 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1777 "DSP_R (m) = RSWAT (R[n]) << 16;",
1778 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1780 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1781 "DSP_R (m) = RSWAT (R[n]) << 16;",
1782 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1784 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1785 "WWAT (R[n], DSP_R (m) >> 16);",
1787 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1788 "WWAT (R[n], DSP_R (m) >> 16);",
1789 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1791 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1792 "WWAT (R[n], DSP_R (m) >> 16);",
1793 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1795 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1796 "DSP_R (m) = RLAT (R[n]);",
1798 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1799 "DSP_R (m) = RLAT (R[n]);",
1800 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1802 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1803 "DSP_R (m) = RLAT (R[n]);",
1804 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1806 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1807 "WLAT (R[n], DSP_R (m));",
1809 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1810 "WLAT (R[n], DSP_R (m));",
1811 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1813 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1814 "WLAT (R[n], DSP_R (m));",
1815 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1817 { "", "", "nopx nopy", "1111000000000000",
1820 { "", "", "ppi", "1111100000000000",
1821 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1822 "ppi_insn (RIAT (nip));",
1823 "SET_NIP (nip + 2);",
1824 "iword &= 0xf7ff; goto top;",
1831 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1832 "int Sz = DSP_R (z) & 0xffff0000;",
1836 "else if (i >= 128 - 16)",
1837 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1840 " RAISE_EXCEPTION (SIGILL);",
1843 "res &= 0xffff0000;",
1847 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1848 "int Sz = DSP_R (z);",
1849 "int Sz_grd = GET_DSP_GRD (z);",
1861 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1863 " res_grd = SEXT (res_grd);",
1864 " carry = res_grd & 1;",
1866 "else if (i >= 96)",
1871 " res_grd = SIGN32 (Sz_grd);",
1876 " res = Sz >> i | Sz_grd << 32 - i;",
1877 " res_grd = Sz_grd >> i;",
1879 " carry = Sz >> (i - 1) & 1;",
1883 " RAISE_EXCEPTION (SIGILL);",
1886 "COMPUTE_OVERFLOW;",
1887 "greater_equal = 0;",
1889 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1890 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1891 "if (res == 0x80000000)",
1892 " res = 0x7fffffff;",
1894 "DSP_GRD (g) = SIGN32 (res);",
1897 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1898 "int Sx = DSP_R (x);",
1899 "int Sx_grd = GET_DSP_GRD (x);",
1900 "int Sy = DSP_R (y);",
1901 "int Sy_grd = SIGN32 (Sy);",
1903 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1904 "if (res == 0x80000000)",
1905 " res = 0x7fffffff;",
1907 "DSP_GRD (g) = SIGN32 (res);",
1911 "carry = (unsigned) res > (unsigned) Sx;",
1912 "res_grd = Sx_grd - Sy_grd - carry;",
1913 "COMPUTE_OVERFLOW;",
1916 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1917 "int Sx = DSP_R (x);",
1918 "int Sx_grd = GET_DSP_GRD (x);",
1919 "int Sy = DSP_R (y);",
1920 "int Sy_grd = SIGN32 (Sy);",
1922 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1923 "if (res == 0x80000000)",
1924 " res = 0x7fffffff;",
1926 "DSP_GRD (g) = SIGN32 (res);",
1930 "carry = (unsigned) res < (unsigned) Sx;",
1931 "res_grd = Sx_grd + Sy_grd + carry;",
1932 "COMPUTE_OVERFLOW;",
1934 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1935 "int Sx = DSP_R (x);",
1936 "int Sx_grd = GET_DSP_GRD (x);",
1937 "int Sy = DSP_R (y);",
1938 "int Sy_grd = SIGN32 (Sy);",
1940 "res = Sx - Sy - (DSR & 1);",
1941 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1942 "res_grd = Sx_grd + Sy_grd + carry;",
1943 "COMPUTE_OVERFLOW;",
1946 "if (res || res_grd)\n",
1947 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1949 " DSR |= DSR_MASK_Z | overflow;\n",
1953 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1954 "int Sx = DSP_R (x);",
1955 "int Sx_grd = GET_DSP_GRD (x);",
1956 "int Sy = DSP_R (y);",
1957 "int Sy_grd = SIGN32 (Sy);",
1959 "res = Sx + Sy + (DSR & 1);",
1960 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1961 "res_grd = Sx_grd + Sy_grd + carry;",
1962 "COMPUTE_OVERFLOW;",
1965 "if (res || res_grd)\n",
1966 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1968 " DSR |= DSR_MASK_Z | overflow;\n",
1972 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1973 "int Sx = DSP_R (x);",
1974 "int Sx_grd = GET_DSP_GRD (x);",
1975 "int Sy = DSP_R (y);",
1976 "int Sy_grd = SIGN32 (Sy);",
1978 "z = 17; /* Ignore result. */",
1980 "carry = (unsigned) res > (unsigned) Sx;",
1981 "res_grd = Sx_grd - Sy_grd - carry;",
1982 "COMPUTE_OVERFLOW;",
1985 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1987 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1989 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
1990 "/* FIXME: duplicate code pabs. */",
1992 "res_grd = GET_DSP_GRD (x);",
1998 " carry = (res != 0); /* The manual has a bug here. */",
1999 " res_grd = -res_grd - carry;",
2001 "COMPUTE_OVERFLOW;",
2002 "/* ??? The re-computing of overflow after",
2003 " saturation processing is specific to pabs. */",
2004 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2007 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2009 "res_grd = GET_DSP_GRD (x);",
2015 " carry = (res != 0); /* The manual has a bug here. */",
2016 " res_grd = -res_grd - carry;",
2018 "COMPUTE_OVERFLOW;",
2019 "/* ??? The re-computing of overflow after",
2020 " saturation processing is specific to pabs. */",
2021 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2025 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2026 "/* FIXME: duplicate code prnd. */",
2027 "int Sx = DSP_R (x);",
2028 "int Sx_grd = GET_DSP_GRD (x);",
2030 "res = (Sx + 0x8000) & 0xffff0000;",
2031 "carry = (unsigned) res < (unsigned) Sx;",
2032 "res_grd = Sx_grd + carry;",
2033 "COMPUTE_OVERFLOW;",
2036 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2037 "int Sx = DSP_R (x);",
2038 "int Sx_grd = GET_DSP_GRD (x);",
2040 "res = (Sx + 0x8000) & 0xffff0000;",
2041 "carry = (unsigned) res < (unsigned) Sx;",
2042 "res_grd = Sx_grd + carry;",
2043 "COMPUTE_OVERFLOW;",
2047 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2048 "/* FIXME: duplicate code pabs. */",
2052 "greater_equal = DSR_MASK_G;",
2062 " res = 0x7fffffff;",
2065 " overflow = DSR_MASK_V;",
2066 " greater_equal = 0;",
2071 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2075 "greater_equal = DSR_MASK_G;",
2085 " res = 0x7fffffff;",
2088 " overflow = DSR_MASK_V;",
2089 " greater_equal = 0;",
2094 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2095 "/* FIXME: duplicate code prnd. */",
2096 "int Sy = DSP_R (y);",
2097 "int Sy_grd = SIGN32 (Sy);",
2099 "res = (Sy + 0x8000) & 0xffff0000;",
2100 "carry = (unsigned) res < (unsigned) Sy;",
2101 "res_grd = Sy_grd + carry;",
2102 "COMPUTE_OVERFLOW;",
2105 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2106 "int Sy = DSP_R (y);",
2107 "int Sy_grd = SIGN32 (Sy);",
2109 "res = (Sy + 0x8000) & 0xffff0000;",
2110 "carry = (unsigned) res < (unsigned) Sy;",
2111 "res_grd = Sy_grd + carry;",
2112 "COMPUTE_OVERFLOW;",
2115 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2116 "int Sx = DSP_R (x) & 0xffff0000;",
2117 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2121 "else if (Sy >= 128 - 16)",
2122 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2125 " RAISE_EXCEPTION (SIGILL);",
2128 "goto cond_logical;",
2130 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2131 "int Sx = DSP_R (x);",
2132 "int Sx_grd = GET_DSP_GRD (x);",
2133 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2145 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2147 " res_grd = SEXT (res_grd);",
2148 " carry = res_grd & 1;",
2150 "else if (Sy >= 96)",
2155 " res_grd = SIGN32 (Sx_grd);",
2160 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
2161 " res_grd = Sx_grd >> Sy;",
2163 " carry = Sx >> (Sy - 1) & 1;",
2167 " RAISE_EXCEPTION (SIGILL);",
2170 "COMPUTE_OVERFLOW;",
2171 "greater_equal = 0;",
2173 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2174 "int Sx = DSP_R (x);",
2175 "int Sx_grd = GET_DSP_GRD (x);",
2176 "int Sy = DSP_R (y);",
2177 "int Sy_grd = SIGN32 (Sy);",
2180 "carry = (unsigned) res > (unsigned) Sx;",
2181 "res_grd = Sx_grd - Sy_grd - carry;",
2182 "COMPUTE_OVERFLOW;",
2185 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2186 "int Sx = DSP_R (x);",
2187 "int Sx_grd = GET_DSP_GRD (x);",
2188 "int Sy = DSP_R (y);",
2189 "int Sy_grd = SIGN32 (Sy);",
2192 "carry = (unsigned) res > (unsigned) Sy;",
2193 "res_grd = Sy_grd - Sx_grd - carry;",
2194 "COMPUTE_OVERFLOW;",
2197 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2198 "int Sx = DSP_R (x);",
2199 "int Sx_grd = GET_DSP_GRD (x);",
2200 "int Sy = DSP_R (y);",
2201 "int Sy_grd = SIGN32 (Sy);",
2204 "carry = (unsigned) res < (unsigned) Sx;",
2205 "res_grd = Sx_grd + Sy_grd + carry;",
2206 "COMPUTE_OVERFLOW;",
2209 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2210 "res = DSP_R (x) & DSP_R (y);",
2212 "res &= 0xffff0000;",
2214 "if (iword & 0x200)\n",
2215 " goto assign_z;\n",
2219 "greater_equal = 0;",
2222 " DSR |= res >> 26 & DSR_MASK_N;\n",
2224 " DSR |= DSR_MASK_Z;\n",
2225 "goto assign_dc;\n",
2227 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2228 "res = DSP_R (x) ^ DSP_R (y);",
2229 "goto cond_logical;",
2231 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2232 "res = DSP_R (x) | DSP_R (y);",
2233 "goto cond_logical;",
2235 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2236 "int Sx = DSP_R (x);",
2237 "int Sx_grd = GET_DSP_GRD (x);",
2239 "res = Sx - 0x10000;",
2240 "carry = res > Sx;",
2241 "res_grd = Sx_grd - carry;",
2242 "COMPUTE_OVERFLOW;",
2244 "res &= 0xffff0000;",
2246 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2247 "int Sx = DSP_R (x);",
2248 "int Sx_grd = GET_DSP_GRD (x);",
2250 "res = Sx + 0x10000;",
2251 "carry = res < Sx;",
2252 "res_grd = Sx_grd + carry;",
2253 "COMPUTE_OVERFLOW;",
2255 "res &= 0xffff0000;",
2257 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2258 "int Sy = DSP_R (y);",
2259 "int Sy_grd = SIGN32 (Sy);",
2261 "res = Sy - 0x10000;",
2262 "carry = res > Sy;",
2263 "res_grd = Sy_grd - carry;",
2264 "COMPUTE_OVERFLOW;",
2266 "res &= 0xffff0000;",
2268 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2269 "int Sy = DSP_R (y);",
2270 "int Sy_grd = SIGN32 (Sy);",
2272 "res = Sy + 0x10000;",
2273 "carry = res < Sy;",
2274 "res_grd = Sy_grd + carry;",
2275 "COMPUTE_OVERFLOW;",
2277 "res &= 0xffff0000;",
2279 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2284 "greater_equal = 1;",
2286 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2287 "/* Do multiply. */",
2288 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2289 "if (res == 0x80000000)",
2290 " res = 0x7fffffff;",
2292 "DSP_GRD (g) = SIGN32 (res);",
2293 "/* FIXME: update DSR based on results of multiply! */",
2301 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2302 "unsigned Sx = DSP_R (x);",
2303 "int Sx_grd = GET_DSP_GRD (x);",
2308 " Sx_grd = ~Sx_grd;",
2322 " if (Sx & ~0 << i)",
2330 "res_grd = SIGN32 (res);",
2335 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2336 "unsigned Sy = DSP_R (y);",
2345 " if (Sy & ~0 << i)",
2353 "res_grd = SIGN32 (res);",
2358 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2359 "int Sx = DSP_R (x);",
2360 "int Sx_grd = GET_DSP_GRD (x);",
2363 "carry = res != 0;",
2364 "res_grd = 0 - Sx_grd - carry;",
2365 "COMPUTE_OVERFLOW;",
2368 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2370 "res_grd = GET_DSP_GRD (x);",
2372 "COMPUTE_OVERFLOW;",
2375 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2376 "int Sy = DSP_R (y);",
2377 "int Sy_grd = SIGN32 (Sy);",
2380 "carry = res != 0;",
2381 "res_grd = 0 - Sy_grd - carry;",
2382 "COMPUTE_OVERFLOW;",
2385 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2387 "res_grd = SIGN32 (res);",
2389 "COMPUTE_OVERFLOW;",
2392 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2394 "res_grd = SIGN32 (res);",
2397 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2399 "res_grd = SIGN32 (res);",
2402 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2403 "if (0xa05f >> z & 1)",
2404 " RAISE_EXCEPTION (SIGILL);",
2406 " MACH = DSP_R (z);",
2409 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2410 "if (0xa05f >> z & 1)",
2411 " RAISE_EXCEPTION (SIGILL);",
2413 " MACL = DSP_R (z) = res;",
2417 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2418 "int Sx = DSP_R (x);",
2420 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2421 "res_grd = GET_DSP_GRD (x);",
2424 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2427 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2428 "int Sy = DSP_R (y);",
2430 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2431 "res_grd = SIGN32 (Sy);",
2434 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2440 /* Tables of things to put into enums for sh-opc.h */
2441 static char *nibble_type_list[] =
2476 char *arg_type_list[] =
2510 make_enum_list (name, s)
2515 printf ("typedef enum {\n");
2518 printf ("\t%s,\n", *s);
2522 printf ("} %s;\n", name);
2534 memcpy (bufa, a->code, 4);
2535 memcpy (bufa + 4, a->code + 12, 4);
2538 memcpy (bufb, b->code, 4);
2539 memcpy (bufb + 4, b->code + 12, 4);
2541 diff = strcmp (bufa, bufb);
2542 /* Stabilize the sort, so that later entries can override more general
2543 preceding entries. */
2544 return diff ? diff : a - b;
2558 qsort (tab, len, sizeof (*p), qfunc);
2566 for (p = tab; p->name; p++)
2568 printf ("%s %-30s\n", p->code, p->name);
2572 static unsigned short table[1 << 16];
2574 static int warn_conflicts = 0;
2577 conflict_warn (val, i)
2584 fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2585 val, i, table[val]);
2587 for (ix = sizeof (tab) / sizeof (tab[0]); ix >= 0; ix--)
2588 if (tab[ix].index == i || tab[ix].index == j)
2590 key = ((tab[ix].code[0] - '0') << 3) +
2591 ((tab[ix].code[1] - '0') << 2) +
2592 ((tab[ix].code[2] - '0') << 1) +
2593 ((tab[ix].code[3] - '0'));
2595 if (val >> 12 == key)
2596 fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name);
2599 for (ix = sizeof (movsxy_tab) / sizeof (movsxy_tab[0]); ix >= 0; ix--)
2600 if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
2602 key = ((movsxy_tab[ix].code[0] - '0') << 3) +
2603 ((movsxy_tab[ix].code[1] - '0') << 2) +
2604 ((movsxy_tab[ix].code[2] - '0') << 1) +
2605 ((movsxy_tab[ix].code[3] - '0'));
2607 if (val >> 12 == key)
2608 fprintf (stderr, " %s -- %s\n",
2609 movsxy_tab[ix].code, movsxy_tab[ix].name);
2612 for (ix = sizeof (ppi_tab) / sizeof (ppi_tab[0]); ix >= 0; ix--)
2613 if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
2615 key = ((ppi_tab[ix].code[0] - '0') << 3) +
2616 ((ppi_tab[ix].code[1] - '0') << 2) +
2617 ((ppi_tab[ix].code[2] - '0') << 1) +
2618 ((ppi_tab[ix].code[3] - '0'));
2620 if (val >> 12 == key)
2621 fprintf (stderr, " %s -- %s\n",
2622 ppi_tab[ix].code, ppi_tab[ix].name);
2626 /* Take an opcode, expand all varying fields in it out and fill all the
2627 right entries in 'table' with the opcode index. */
2630 expand_opcode (val, i, s)
2637 if (warn_conflicts && table[val] != 0)
2638 conflict_warn (val, i);
2648 fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
2652 /* Consume an arbitrary number of ones and zeros. */
2654 j = (j << 1) + (s[m++] - '0');
2655 } while (s[m] == '0' || s[m] == '1');
2656 expand_opcode ((val << m) | j, i, s + m);
2658 case 'N': /* NN -- four-way fork */
2659 for (j = 0; j < 4; j++)
2660 expand_opcode ((val << 2) | j, i, s + 2);
2662 case 'x': /* xx or xy -- two-way or four-way fork */
2663 for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1))
2664 expand_opcode ((val << 2) | j, i, s + 2);
2666 case 'y': /* yy or yx -- two-way or four-way fork */
2667 for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++)
2668 expand_opcode ((val << 2) | j, i, s + 2);
2670 case '?': /* Seven-way "wildcard" fork for movxy */
2671 expand_opcode ((val << 2), i, s + 2);
2672 for (j = 1; j < 4; j++)
2674 expand_opcode ((val << 2) | j, i, s + 2);
2675 expand_opcode ((val << 2) | (j + 16), i, s + 2);
2678 case 'i': /* eg. "i8*1" */
2679 case '.': /* "...." is a wildcard */
2682 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2683 for (j = 0; j < 16; j++)
2684 expand_opcode ((val << 4) | j, i, s + 4);
2687 /* eeee -- even numbered register:
2689 for (j = 0; j < 15; j += 2)
2690 expand_opcode ((val << 4) | j, i, s + 4);
2693 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2694 MMMM -- 10-way fork */
2695 expand_opcode ((val << 4) | 5, i, s + 4);
2696 for (j = 7; j < 16; j++)
2697 expand_opcode ((val << 4) | j, i, s + 4);
2701 GGGG -- two-way fork */
2702 for (j = 13; j <= 15; j +=2)
2703 expand_opcode ((val << 4) | j, i, s + 4);
2706 /* ssss -- 10-way fork */
2707 /* System registers mach, macl, pr: */
2708 for (j = 0; j < 3; j++)
2709 expand_opcode ((val << 4) | j, i, s + 4);
2710 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2711 for (j = 5; j < 12; j++)
2712 expand_opcode ((val << 4) | j, i, s + 4);
2715 /* XX/XY -- 2/4 way fork. */
2716 for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1))
2717 expand_opcode ((val << 2) | j, i, s + 2);
2720 /* aa/ax -- 2/4 way fork. */
2721 for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1))
2722 expand_opcode ((val << 2) | j, i, s + 2);
2725 /* YY/YX -- 2/4 way fork. */
2726 for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1)
2727 expand_opcode ((val << 2) | j, i, s + 2);
2730 /* AA/AY: 2/4 way fork. */
2731 for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1)
2732 expand_opcode ((val << 2) | j, i, s + 2);
2735 /* vv(VV) -- 4(16) way fork. */
2736 /* Vector register fv0/4/8/12. */
2739 /* 2 vector registers. */
2740 for (j = 0; j < 15; j++)
2741 expand_opcode ((val << 4) | j, i, s + 4);
2745 /* 1 vector register. */
2746 for (j = 0; j < 4; j += 1)
2747 expand_opcode ((val << 2) | j, i, s + 2);
2754 /* Print the jump table used to index an opcode into a switch
2758 dumptable (name, size, start)
2768 printf ("unsigned short %s[%d]={\n", name, size);
2769 while (i < start + size)
2773 printf ("/* 0x%x */\n", i);
2780 printf ("%2d", table[i + j + k]);
2799 static int index = 1;
2802 for (; p->name; p++)
2805 expand_opcode (0, p->index, p->code);
2809 /* Table already contains all the switch case tags for 16-bit opcode double
2810 data transfer (ddt) insns, and the switch case tag for processing parallel
2811 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2812 latter tag to represent all combinations of ppi with ddt. */
2818 for (i = 0xf000; i < 0xf400; i++)
2820 table[i + 0x800] = table[0xf800];
2827 for (; p->name; p++)
2836 printf (" /* %s %s */\n", p->name, p->code);
2837 printf (" case %d: \n", p->index);
2845 fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2850 /* Wildcard expansion, nothing to do here. */
2854 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2858 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2870 printf (" int n = (iword >> 8) & 0xf;\n");
2875 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2879 if (s[1] == 'y') /* xy */
2881 printf (" int n = (iword & 3) ? \n");
2882 printf (" ((iword >> 9) & 1) + 4 : \n");
2883 printf (" REG_xy ((iword >> 8) & 3);\n");
2886 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2891 if (s[1] == 'x') /* yx */
2893 printf (" int n = (iword & 0xc) ? \n");
2894 printf (" ((iword >> 8) & 1) + 6 : \n");
2895 printf (" REG_yx ((iword >> 8) & 3);\n");
2898 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2907 printf (" int m = (iword >> 4) & 0xf;\n");
2911 if (s[1] == 'Y') /* XY */
2913 printf (" int m = (iword & 3) ? \n");
2914 printf (" ((iword >> 7) & 1) + 8 : \n");
2915 printf (" DSP_xy ((iword >> 6) & 3);\n");
2918 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2922 if (s[1] == 'x') /* ax */
2924 printf (" int m = (iword & 3) ? \n");
2925 printf (" 7 - ((iword >> 6) & 2) : \n");
2926 printf (" DSP_ax ((iword >> 6) & 3);\n");
2929 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2933 if (s[1] == 'X') /* YX */
2935 printf (" int m = (iword & 0xc) ? \n");
2936 printf (" ((iword >> 6) & 1) + 10 : \n");
2937 printf (" DSP_yx ((iword >> 6) & 3);\n");
2940 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2944 if (s[1] == 'Y') /* AY */
2946 printf (" int m = (iword & 0xc) ? \n");
2947 printf (" 7 - ((iword >> 5) & 2) : \n");
2948 printf (" DSP_ay ((iword >> 6) & 3);\n");
2951 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2956 printf (" int i = (iword & 0x");
2962 "gensim_caselist: Unknown char '%c' in %s\n",
2983 "gensim_caselist: Unknown char '%c' in %s\n",
2987 case '.': /* eg. "i12." */
3004 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3005 sextbit - 1, sextbit - 1);
3009 printf (" TB (m,n);\n");
3011 printf (" TL (m);\n");
3013 printf (" TL (n);\n");
3018 for (r = p->refs; *r; r++)
3020 if (*r == 'f') printf (" CREF (15);\n");
3024 printf (" int i = n;\n");
3026 printf (" CREF (i);\n");
3027 printf (" } while (i-- > 0);\n");
3033 printf (" int i = n;\n");
3035 printf (" CREF (i);\n");
3036 printf (" } while (i++ < 14);\n");
3039 if (*r == '0') printf (" CREF (0);\n");
3040 if (*r == '8') printf (" CREF (8);\n");
3041 if (*r == '9') printf (" CREF (9);\n");
3042 if (*r == 'n') printf (" CREF (n);\n");
3043 if (*r == 'm') printf (" CREF (m);\n");
3048 for (j = 0; j < MAX_NR_STUFF; j++)
3052 printf (" %s\n", p->stuff[j]);
3060 for (r = p->defs; *r; r++)
3062 if (*r == 'f') printf (" CDEF (15);\n");
3066 printf (" int i = n;\n");
3068 printf (" CDEF (i);\n");
3069 printf (" } while (i-- > 0);\n");
3075 printf (" int i = n;\n");
3077 printf (" CDEF (i);\n");
3078 printf (" } while (i++ < 14);\n");
3081 if (*r == '0') printf (" CDEF (0);\n");
3082 if (*r == 'n') printf (" CDEF (n);\n");
3083 if (*r == 'm') printf (" CDEF (m);\n");
3087 printf (" break;\n");
3096 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3097 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3098 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3099 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3100 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3101 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3102 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3103 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3104 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3105 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3106 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3107 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3108 printf (" switch (jump_table[iword]) {\n");
3110 gensim_caselist (tab);
3111 gensim_caselist (movsxy_tab);
3113 printf (" default:\n");
3115 printf (" RAISE_EXCEPTION (SIGILL);\n");
3126 for (p = tab; p->name; p++)
3129 printf ("#define OPC_");
3143 printf (" %d\n",p->index);
3147 static int ppi_index;
3149 /* Take a ppi code, expand all varying fields in it and fill all the
3150 right entries in 'table' with the opcode index.
3151 NOTE: tail recursion optimization removed for simplicity. */
3154 expand_ppi_code (val, i, s)
3164 fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]);
3169 if (warn_conflicts && table[val] != 0)
3170 conflict_warn (val, i);
3172 /* The last four bits are disregarded for the switch table. */
3176 /* Four-bit expansion. */
3177 for (j = 0; j < 16; j++)
3178 expand_ppi_code ((val << 4) + j, i, s + 4);
3182 expand_ppi_code ((val << 1), i, s + 1);
3185 expand_ppi_code ((val << 1) + 1, i, s + 1);
3190 expand_ppi_code ((val << 1), i, s + 1);
3191 expand_ppi_code ((val << 1) + 1, i, s + 1);
3194 expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2);
3195 expand_ppi_code ((val << 2) + 2, i, s + 2);
3196 expand_ppi_code ((val << 2) + 3, i, s + 2);
3207 for (p = ppi_tab; p->name; p++)
3209 p->index = ppi_index++;
3210 expand_ppi_code (0, p->index, p->code);
3219 printf ("#define DSR_MASK_G 0x80\n");
3220 printf ("#define DSR_MASK_Z 0x40\n");
3221 printf ("#define DSR_MASK_N 0x20\n");
3222 printf ("#define DSR_MASK_V 0x10\n");
3224 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3225 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3226 printf (" if (overflow && S) \\\n");
3228 printf (" if (res_grd & 0x80) \\\n");
3230 printf (" res = 0x80000000; \\\n");
3231 printf (" res_grd |= 0xff; \\\n");
3233 printf (" else \\\n");
3235 printf (" res = 0x7fffffff; \\\n");
3236 printf (" res_grd &= ~0xff; \\\n");
3238 printf (" overflow = 0; \\\n");
3240 printf ("} while (0)\n");
3242 printf ("#define ADD_SUB_GE \\\n");
3243 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3245 printf ("static void\n");
3246 printf ("ppi_insn (iword)\n");
3247 printf (" int iword;\n");
3249 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3250 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
3251 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3252 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
3253 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3254 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
3255 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3256 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
3257 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3258 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
3259 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3260 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
3262 printf (" int z;\n");
3263 printf (" int res, res_grd;\n");
3264 printf (" int carry, overflow, greater_equal;\n");
3266 printf (" switch (ppi_table[iword >> 4]) {\n");
3268 for (; p->name; p++)
3276 printf (" /* %s %s */\n", p->name, p->code);
3277 printf (" case %d: \n", p->index);
3280 for (shift = 16; *s; )
3285 printf (" int i = (iword >> 4) & 0x7f;\n");
3295 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3301 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3302 printf ("\treturn;\n");
3304 printf (" case %d: \n", p->index + 1);
3316 printf (" z = iword & 0xf;\n");
3324 else if (havedecl == 2)
3326 for (j = 0; j < MAX_NR_STUFF; j++)
3331 (havedecl == 2 ? " " : ""),
3339 printf (" if (iword & 0x200)\n");
3340 printf (" goto assign_z;\n");
3342 printf (" break;\n");
3346 printf (" default:\n");
3348 printf (" RAISE_EXCEPTION (SIGILL);\n");
3349 printf (" return;\n");
3352 printf (" DSR &= ~0xf1;\n");
3353 printf (" if (res || res_grd)\n");
3354 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3356 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3357 printf (" assign_dc:\n");
3358 printf (" switch (DSR >> 1 & 7)\n");
3360 printf (" case 0: /* Carry Mode */\n");
3361 printf (" DSR |= carry;\n");
3362 printf (" case 1: /* Negative Value Mode */\n");
3363 printf (" DSR |= res_grd >> 7 & 1;\n");
3364 printf (" case 2: /* Zero Value Mode */\n");
3365 printf (" DSR |= DSR >> 6 & 1;\n");
3366 printf (" case 3: /* Overflow mode\n");
3367 printf (" DSR |= overflow >> 4;\n");
3368 printf (" case 4: /* Signed Greater Than Mode */\n");
3369 printf (" DSR |= DSR >> 7 & 1;\n");
3370 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
3371 printf (" DSR |= greater_equal >> 7;\n");
3373 printf (" assign_z:\n");
3374 printf (" if (0xa05f >> z & 1)\n");
3376 printf (" RAISE_EXCEPTION (SIGILL);\n");
3377 printf (" return;\n");
3379 printf (" DSP_R (z) = res;\n");
3380 printf (" DSP_GRD (z) = res_grd;\n");
3389 /* Verify the table before anything else. */
3392 for (p = tab; p->name; p++)
3394 /* Check that the code field contains 16 bits. */
3395 if (strlen (p->code) != 16)
3397 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
3398 p->code, strlen (p->code), p->name);
3404 /* Now generate the requested data. */
3407 if (ac > 2 && strcmp (av[2], "-w") == 0)
3411 if (strcmp (av[1], "-t") == 0)
3415 else if (strcmp (av[1], "-d") == 0)
3419 else if (strcmp (av[1], "-s") == 0)
3422 dumptable ("sh_jump_table", 1 << 16, 0);
3424 memset (table, 0, sizeof table);
3425 filltable (movsxy_tab);
3426 expand_ppi_movxy ();
3427 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3429 memset (table, 0, sizeof table);
3431 dumptable ("ppi_table", 1 << 12, 0);
3433 else if (strcmp (av[1], "-x") == 0)
3436 filltable (movsxy_tab);
3439 else if (strcmp (av[1], "-p") == 0)
3446 fprintf (stderr, "Opcode table generation no longer supported.\n");