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 "/* FIXME: The result may be implementation-defined if it is outside */",
219 "/* the range of signed int (i.e. if R[n] was negative and R0 == 1). */",
220 "else R[n] = R[n] / (unsigned int) R0;",
223 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
224 "R[n] = (R[n] * R0) & 0xffffffff;",
227 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
228 "int regn = (R[n] >> 2) & 0x1f;",
229 "int bankn = (R[n] >> 7) & 0x1ff;",
231 " regn = 19; /* FIXME what should happen? */",
232 "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
235 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
236 "int regn = (R[n] >> 2) & 0x1f;",
237 "int bankn = (R[n] >> 7) & 0x1ff;",
239 " regn = 19; /* FIXME what should happen? */",
240 "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
242 { "", "", "resbank", "0000000001011011",
244 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
245 /* FIXME: cdef all */
246 "if (BO) { /* Bank Overflow */",
247 /* FIXME: how do we know when to reset BO? */
248 " for (i = 0; i <= 14; i++) {",
249 " R[i] = RLAT (R[15]);",
253 " PR = RLAT (R[15]);",
256 " GBR = RLAT (R[15]);",
259 " MACH = RLAT (R[15]);",
262 " MACL = RLAT (R[15]);",
266 "else if (BANKN == 0) /* Bank Underflow */",
267 " RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */
269 " SET_BANKN (BANKN - 1);",
270 " for (i = 0; i <= 14; i++)",
271 " R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
272 " MACH = saved_state.asregs.regstack[BANKN].regs[15];",
273 " PR = saved_state.asregs.regstack[BANKN].regs[17];",
274 " GBR = saved_state.asregs.regstack[BANKN].regs[18];",
275 " MACL = saved_state.asregs.regstack[BANKN].regs[19];",
278 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
279 "/* Push Rn...R0 (if n==15, push pr and R14...R0). */",
284 " WLAT (R[15], PR);",
286 " WLAT (R[15], R[n]);",
287 "} while (n-- > 0);",
289 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
290 "/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */",
295 " PR = RLAT (R[15]);",
297 " R[i] = RLAT (R[15]);",
299 "} while (i++ < n);",
301 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
302 "/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */
308 " WLAT (R[15], PR);",
310 " WLAT (R[15], R[i]);",
311 "} while (i-- > n);",
313 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
314 "/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */
318 " PR = RLAT (R[15]);",
320 " R[n] = RLAT (R[15]);",
322 "} while (n++ < 15);",
324 { "", "", "nott", "0000000001101000",
325 "SET_SR_T (T == 0);",
328 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
329 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
331 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
333 " Delay_Slot (PC + 2);",
337 { "", "", "clrmac", "0000000000101000",
342 { "", "", "clrs", "0000000001001000",
346 { "", "", "clrt", "0000000000001000",
351 { "", "", "clrdmxy", "0000000010001000",
352 "saved_state.asregs.cregs.named.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
355 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
356 "SET_SR_T (R0 == SEXT (i));",
358 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
359 "SET_SR_T (R[n] == R[m]);",
361 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
362 "SET_SR_T (R[n] >= R[m]);",
364 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
365 "SET_SR_T (R[n] > R[m]);",
367 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
368 "SET_SR_T (UR[n] > UR[m]);",
370 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
371 "SET_SR_T (UR[n] >= UR[m]);",
373 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
374 "SET_SR_T (R[n] > 0);",
376 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
377 "SET_SR_T (R[n] >= 0);",
379 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
380 "ult = R[n] ^ R[m];",
381 "SET_SR_T (((ult & 0xff000000) == 0)",
382 " | ((ult & 0xff0000) == 0)",
383 " | ((ult & 0xff00) == 0)",
384 " | ((ult & 0xff) == 0));",
387 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
388 "SET_SR_Q ((R[n] & sbit) != 0);",
389 "SET_SR_M ((R[m] & sbit) != 0);",
390 "SET_SR_T (M != Q);",
393 { "", "", "div0u", "0000000000011001",
399 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
400 "div1 (&R0, m, n/*, T*/);",
403 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
404 "dmul (1/*signed*/, R[n], R[m]);",
407 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
408 "dmul (0/*unsigned*/, R[n], R[m]);",
411 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
413 "SET_SR_T (R[n] == 0);",
416 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
417 "R[n] = SEXT (R[m]);",
419 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
420 "R[n] = SEXTW (R[m]);",
423 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
424 "R[n] = (R[m] & 0xff);",
426 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
427 "R[n] = (R[m] & 0xffff);",
431 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
432 "FP_UNARY (n, fabs);",
433 "/* FIXME: FR (n) &= 0x7fffffff; */",
437 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
442 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
443 "FP_CMP (n, ==, m);",
446 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
451 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
452 "if (! FPSCR_PR || n & 1)",
453 " RAISE_EXCEPTION (SIGILL);",
467 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
468 "if (! FPSCR_PR || n & 1)",
469 " RAISE_EXCEPTION (SIGILL);",
483 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
485 "/* FIXME: check for DP and (n & 1) == 0? */",
489 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
491 " RAISE_EXCEPTION (SIGILL);",
495 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
496 " RAISE_EXCEPTION (SIGILL);",
497 " /* FIXME: check for nans and infinities. */",
498 " fsum += FR (v1+0) * FR (v2+0);",
499 " fsum += FR (v1+1) * FR (v2+1);",
500 " fsum += FR (v1+2) * FR (v2+2);",
501 " fsum += FR (v1+3) * FR (v2+3);",
502 " SET_FR (v1+3, fsum);",
507 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
508 "SET_FR (n, (float) 0.0);",
509 "/* FIXME: check for DP and (n & 1) == 0? */",
513 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
514 "SET_FR (n, (float) 1.0);",
515 "/* FIXME: check for DP and (n & 1) == 0? */",
519 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
530 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
533 " SET_DR (n, (double) FPUL);",
536 " SET_FR (n, (float) FPUL);",
541 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
542 "SET_FR (n, FR (m) * FR (0) + FR (n));",
543 "/* FIXME: check for DP and (n & 1) == 0? */",
547 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
550 " int ni = XD_TO_XF (n);",
551 " int mi = XD_TO_XF (m);",
552 " SET_XF (ni + 0, XF (mi + 0));",
553 " SET_XF (ni + 1, XF (mi + 1));",
557 " SET_FR (n, FR (m));",
561 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
570 " WLAT (R[n], FI (m));",
574 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
583 " SET_FI (n, RLAT (R[m]));",
587 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
588 "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
589 " and mov.bwl <REG_N>, @(disp12,<REG_M>)",
590 " and mov.bwl @(disp12,<REG_N>),<REG_M>",
591 " and movu.bw @(disp12,<REG_N>),<REG_M>. */",
592 "int word2 = RIAT (nip);",
593 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
594 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
596 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
599 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
609 " SET_FI (n, RLAT (R[m]));",
614 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
625 " WLAT (R[n], FI (m));",
629 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
633 " RDAT (R[0]+R[m], n);",
638 " SET_FI (n, RLAT (R[0] + R[m]));",
642 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
646 " WDAT (R[0]+R[n], m);",
651 " WLAT ((R[0]+R[n]), FI (m));",
656 See fmov instructions above for move to/from extended fp registers. */
659 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
664 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
669 { "", "", "fpchg", "1111011111111101",
670 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
674 { "", "", "frchg", "1111101111111101",
676 " RAISE_EXCEPTION (SIGILL);",
677 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
678 " RAISE_EXCEPTION (SIGILL);",
680 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
684 { "", "", "fsca", "1111eeee11111101",
686 " RAISE_EXCEPTION (SIGILL);",
687 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
688 " RAISE_EXCEPTION (SIGILL);",
691 " SET_FR (n, fsca_s (FPUL, &sin));",
692 " SET_FR (n+1, fsca_s (FPUL, &cos));",
697 { "", "", "fschg", "1111001111111101",
698 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
702 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
703 "FP_UNARY (n, sqrt);",
707 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
709 " RAISE_EXCEPTION (SIGILL);",
710 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
711 " RAISE_EXCEPTION (SIGILL);",
713 " SET_FR (n, fsrra_s (FR (n)));",
717 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
722 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
725 " if (DR (n) != DR (n)) /* NaN */",
726 " FPUL = 0x80000000;",
728 " FPUL = (int) DR (n);",
731 "if (FR (n) != FR (n)) /* NaN */",
732 " FPUL = 0x80000000;",
734 " FPUL = (int) FR (n);",
738 { "", "", "ftrv <FV_N>", "1111vv0111111101",
740 " RAISE_EXCEPTION (SIGILL);",
743 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
744 " RAISE_EXCEPTION (SIGILL);",
745 " /* FIXME not implemented. */",
746 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
751 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
761 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
762 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
763 "SET_NIP (PT2H (R[n]));",
765 "Delay_Slot (PC + 2);",
768 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
769 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
770 "PR = PH2T (PC + 4);",
772 " gotcall (PR, R[n]);",
773 "SET_NIP (PT2H (R[n]));",
775 "Delay_Slot (PC + 2);",
777 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
778 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
779 "PR = PH2T (PC + 2);",
781 " gotcall (PR, R[n]);",
782 "SET_NIP (PT2H (R[n]));",
784 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
785 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
786 "PR = PH2T (PC + 2);",
788 " gotcall (PR, i + TBR);",
789 "SET_NIP (PT2H (i + TBR));",
792 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
794 "/* FIXME: user mode */",
796 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
798 "/* FIXME: user mode */",
800 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
803 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
805 " DBR = R[n]; /* priv mode */",
807 " RAISE_EXCEPTION (SIGILL); /* user mode */",
809 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
811 " SGR = R[n]; /* priv mode */",
813 " RAISE_EXCEPTION (SIGILL); /* user mode */",
815 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
816 "if (SR_MD)", /* FIXME? */
817 " TBR = R[n]; /* priv mode */",
819 " RAISE_EXCEPTION (SIGILL); /* user mode */",
821 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
823 "CREG (m) = RLAT (R[n]);",
825 "/* FIXME: user mode */",
827 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
829 "SET_SR (RLAT (R[n]));",
831 "/* FIXME: user mode */",
833 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
835 "SET_MOD (RLAT (R[n]));",
838 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
842 " DBR = RLAT (R[n]);",
846 " RAISE_EXCEPTION (SIGILL); /* user mode */",
848 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
852 " SGR = RLAT (R[n]);",
856 " RAISE_EXCEPTION (SIGILL); /* user mode */",
860 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
861 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
863 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
864 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
868 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
870 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
871 "CHECK_INSN_PTR (insn_ptr);",
874 { "", "", "ldrc #<imm>", "10001010i8*1....",
876 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
877 "CHECK_INSN_PTR (insn_ptr);",
881 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
884 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
886 "SREG (m) = RLAT (R[n]);",
889 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
890 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
893 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
894 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
896 "SET_FPSCR (RLAT (R[n]));",
900 { "", "", "ldtlb", "0000000000111000",
901 "/* We don't implement cache or tlb, so this is a noop. */",
904 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
905 "macl (&R0, memory, n, m);",
908 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
909 "macw (&R0, memory, n, m, endianw);",
912 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
915 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
916 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
917 "R[n] = ((i << 24) >> 12) | RIAT (nip);",
918 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
920 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
921 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
922 "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
923 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
925 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
929 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
931 "R0 = RSBAT (i + GBR);",
934 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
936 "R0 = RSBAT (i + R[m]);",
939 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
941 "R[n] = RSBAT (R0 + R[m]);",
944 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
946 "R[n] = RSBAT (R[m]);",
950 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
953 "R0 = RSBAT (R[n]);",
956 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
958 "WBAT (R[n], R[m]);",
960 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
962 "WBAT (i + GBR, R0);",
964 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
966 "WBAT (i + R[m], R0);",
968 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
970 "WBAT (R[n] + R0, R[m]);",
972 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
975 "WBAT (R[n], R[m]);",
977 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
982 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
984 "R[n] = RSBAT (R[m]);",
988 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
990 "R0 = RLAT (i + GBR);",
993 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
995 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
998 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1000 "R[n] = RLAT (i + R[m]);",
1003 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1005 "R[n] = RLAT (R0 + R[m]);",
1008 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1010 "R[n] = RLAT (R[m]);",
1014 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1017 "R0 = RLAT (R[n]);",
1020 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1022 "R[n] = RLAT (R[m]);",
1025 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1027 "WLAT (i + GBR, R0);",
1029 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1031 "WLAT (i + R[n], R[m]);",
1033 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1035 "WLAT (R0 + R[n], R[m]);",
1037 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1040 "WLAT (R[n], R[m]);",
1042 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1047 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1049 "WLAT (R[n], R[m]);",
1052 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1054 "R0 = RSWAT (i + GBR);",
1057 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1059 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1062 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1064 "R0 = RSWAT (i + R[m]);",
1067 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1069 "R[n] = RSWAT (R0 + R[m]);",
1072 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1074 "R[n] = RSWAT (R[m]);",
1078 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1081 "R0 = RSWAT (R[n]);",
1084 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1086 "R[n] = RSWAT (R[m]);",
1089 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1091 "WWAT (i + GBR, R0);",
1093 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1095 "WWAT (i + R[m], R0);",
1097 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1099 "WWAT (R0 + R[n], R[m]);",
1101 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1104 "WWAT (R[n], R[m]);",
1106 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1111 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1113 "WWAT (R[n], R[m]);",
1116 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1117 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1120 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1121 "/* We don't simulate cache, so this insn is identical to mov. */",
1123 "WLAT (R[n], R[0]);",
1126 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1129 "/* if (T) R0 -> (Rn) */",
1131 " WLAT (R[n], R[0]);",
1136 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1140 "R[0] = RLAT (R[n]);",
1141 "/* if (interrupt/exception) 0 -> LDST */",
1142 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1145 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1148 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1151 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1153 "int e = target_little_endian ? 3 : 0;",
1155 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1156 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1159 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1161 "int e = target_little_endian ? 3 : 0;",
1163 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1164 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1168 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1169 "MACL = ((int) R[n]) * ((int) R[m]);",
1171 #if 0 /* FIXME: The above cast to int is not really portable.
1172 It should be replaced by a SEXT32 macro. */
1173 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1174 "MACL = R[n] * R[m];",
1178 /* muls.w - see muls */
1179 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1180 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1183 /* mulu.w - see mulu */
1184 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1185 "MACL = (((unsigned int) (unsigned short) R[n])",
1186 " * ((unsigned int) (unsigned short) R[m]));",
1189 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1193 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1195 "SET_SR_T (ult > 0);",
1196 "R[n] = ult - R[m];",
1197 "SET_SR_T (T || (R[n] > ult));",
1200 { "", "", "nop", "0000000000001001",
1204 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1209 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1210 "/* Except for the effect on the cache - which is not simulated -",
1211 " this is like a nop. */",
1214 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1215 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1216 "/* FIXME: Cache not implemented */",
1219 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1220 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1221 "/* FIXME: Cache not implemented */",
1224 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1225 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1226 "/* FIXME: Cache not implemented */",
1229 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1232 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1235 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1237 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1240 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1241 "/* Except for the effect on the cache - which is not simulated -",
1242 " this is like a nop. */",
1246 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1247 "/* Except for the effect on the cache - which is not simulated -",
1248 " this is like a nop. */",
1252 { "", "", "synco", "0000000010101011",
1253 "/* Except for the effect on the pipeline - which is not simulated -",
1254 " this is like a nop. */",
1257 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1259 "R[n] = (R[n] << 1) | T;",
1263 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1265 "R[n] = (UR[n] >> 1) | (T << 31);",
1269 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1270 "SET_SR_T (R[n] < 0);",
1275 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1276 "SET_SR_T (R[n] & 1);",
1277 "R[n] = UR[n] >> 1;",
1278 "R[n] |= (T << 31);",
1281 { "", "", "rte", "0000000000101011",
1285 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1287 "SET_SR (RLAT (R[15]) & 0x3f3);",
1289 "Delay_Slot (PC + 2);",
1291 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1293 "SET_NIP (PT2H (SPC));",
1295 "Delay_Slot (PC + 2);",
1299 { "", "", "rts", "0000000000001011",
1300 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1301 "SET_NIP (PT2H (PR));",
1303 "Delay_Slot (PC + 2);",
1305 { "", "", "rts/n", "0000000001101011",
1306 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1307 "SET_NIP (PT2H (PR));",
1309 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1310 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1313 "SET_NIP (PT2H (PR));",
1317 { "", "", "setdmx", "0000000010011000",
1318 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1319 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1323 { "", "", "setdmy", "0000000011001000",
1324 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1325 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1329 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1332 { "", "", "setrc #<imm>", "10000010i8*1....",
1333 /* It would be more realistic to let loop_start point to some static
1334 memory that contains an illegal opcode and then give a bus error when
1335 the loop is eventually encountered, but it seems not only simpler,
1336 but also more debugging-friendly to just catch the failure here. */
1337 "if (BUSERROR (RS | RE, maskw))",
1338 " RAISE_EXCEPTION (SIGILL);",
1341 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1342 " CHECK_INSN_PTR (insn_ptr);",
1346 { "", "", "sets", "0000000001011000",
1350 { "", "", "sett", "0000000000011000",
1354 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1355 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1358 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1359 "SET_SR_T (R[n] < 0);",
1363 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1364 "SET_SR_T (R[n] & 1);",
1365 "R[n] = R[n] >> 1;",
1368 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1369 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1372 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1373 "SET_SR_T (R[n] < 0);",
1377 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1380 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1383 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1387 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1388 "SET_SR_T (R[n] & 1);",
1389 "R[n] = UR[n] >> 1;",
1392 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1393 "R[n] = UR[n] >> 2;",
1395 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1396 "R[n] = UR[n] >> 8;",
1398 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1399 "R[n] = UR[n] >> 16;",
1402 { "", "", "sleep", "0000000000011011",
1403 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1406 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1410 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1412 " R[n] = SGR; /* priv mode */",
1414 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1416 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1418 " R[n] = DBR; /* priv mode */",
1420 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1422 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1423 "if (SR_MD)", /* FIXME? */
1424 " R[n] = TBR; /* priv mode */",
1426 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1428 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1431 "WLAT (R[n], CREG (m));",
1433 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1435 "{ /* priv mode */",
1438 " WLAT (R[n], SGR);",
1441 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1443 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1445 "{ /* priv mode */",
1448 " WLAT (R[n], DBR);",
1451 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1454 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1457 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1460 "WLAT (R[n], SREG (m));",
1463 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1467 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1469 "SET_SR_T (ult > R[n]);",
1470 "R[n] = ult - R[m];",
1471 "SET_SR_T (T || (R[n] > ult));",
1474 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1475 "ult = R[n] - R[m];",
1476 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1480 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1481 "R[n] = ((R[m] & 0xffff0000)",
1482 " | ((R[m] << 8) & 0xff00)",
1483 " | ((R[m] >> 8) & 0x00ff));",
1485 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1486 "R[n] = (((R[m] << 16) & 0xffff0000)",
1487 " | ((R[m] >> 16) & 0x00ffff));",
1490 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1492 "ult = RBAT (R[n]);",
1493 "SET_SR_T (ult == 0);",
1494 "WBAT (R[n],ult|0x80);",
1497 { "0", "", "trapa #<imm>", "11000011i8*1....",
1498 "long imm = 0xff & i;",
1499 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1500 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1501 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1506 " WLAT (R[15], GET_SR ());",
1508 " WLAT (R[15], PH2T (PC + 2));",
1510 "else if (!SR_BL) {",
1511 " SSR = GET_SR ();",
1512 " SPC = PH2T (PC + 2);",
1513 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1514 " /* FIXME: EXPEVT = 0x00000160; */",
1516 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1520 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1521 "SET_SR_T ((R[n] & R[m]) == 0);",
1523 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1524 "SET_SR_T ((R0 & i) == 0);",
1526 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1528 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1531 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1534 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1537 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1539 "ult = RBAT (GBR+R0);",
1541 "WBAT (GBR + R0, ult);",
1544 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1545 "R[n] = (((R[n] >> 16) & 0xffff)",
1546 " | ((R[m] << 16) & 0xffff0000));",
1550 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1551 "divl (0, R[n], R[m]);",
1553 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1554 "divl (0, R[n], R[m]);",
1562 /* If this is disabled, the simulator speeds up by about 12% on a
1563 450 MHz PIII - 9% with ACE_FAST.
1564 Maybe we should have separate simulator loops? */
1566 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1569 "DSP_R (m) = RSWAT (R[n]) << 16;",
1570 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1572 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1574 "DSP_R (m) = RSWAT (R[n]) << 16;",
1575 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1577 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1579 "DSP_R (m) = RSWAT (R[n]) << 16;",
1580 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1583 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1585 "DSP_R (m) = RSWAT (R[n]) << 16;",
1586 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1589 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1592 "DSP_R (m) = RSWAT (R[n]);",
1594 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1596 "DSP_R (m) = RSWAT (R[n]);",
1598 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1600 "DSP_R (m) = RSWAT (R[n]);",
1603 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1605 "DSP_R (m) = RSWAT (R[n]);",
1608 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1611 "WWAT (R[n], DSP_R (m) >> 16);",
1613 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1615 "WWAT (R[n], DSP_R (m) >> 16);",
1617 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1619 "WWAT (R[n], DSP_R (m) >> 16);",
1622 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1624 "WWAT (R[n], DSP_R (m) >> 16);",
1627 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1630 "WWAT (R[n], SEXT (DSP_R (m)));",
1632 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1634 "WWAT (R[n], SEXT (DSP_R (m)));",
1636 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1638 "WWAT (R[n], SEXT (DSP_R (m)));",
1641 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1643 "WWAT (R[n], SEXT (DSP_R (m)));",
1646 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1649 "DSP_R (m) = RLAT (R[n]);",
1650 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1652 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1654 "DSP_R (m) = RLAT (R[n]);",
1655 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1657 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1659 "DSP_R (m) = RLAT (R[n]);",
1660 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1663 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1665 "DSP_R (m) = RLAT (R[n]);",
1666 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1669 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1672 "WLAT (R[n], DSP_R (m));",
1674 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1676 "WLAT (R[n], DSP_R (m));",
1678 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1680 "WLAT (R[n], DSP_R (m));",
1683 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1685 "WLAT (R[n], DSP_R (m));",
1688 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1691 "WLAT (R[n], SEXT (DSP_R (m)));",
1693 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1695 "WLAT (R[n], SEXT (DSP_R (m)));",
1697 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1699 "WLAT (R[n], SEXT (DSP_R (m)));",
1702 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1704 "WLAT (R[n], SEXT (DSP_R (m)));",
1707 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1708 "DSP_R (m) = RSWAT (R[n]) << 16;",
1711 " iword &= 0xfd53; goto top;",
1714 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1715 "DSP_R (m) = RLAT (R[n]);",
1717 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1718 "DSP_R (m) = RSWAT (R[n]) << 16;",
1719 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1722 " iword &= 0xfd53; goto top;",
1725 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1726 "DSP_R (m) = RLAT (R[n]);",
1727 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1729 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1730 "DSP_R (m) = RSWAT (R[n]) << 16;",
1731 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1734 " iword &= 0xfd53; goto top;",
1737 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1738 "DSP_R (m) = RLAT (R[n]);",
1739 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1741 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1742 "WWAT (R[n], DSP_R (m) >> 16);",
1745 " iword &= 0xfd53; goto top;",
1748 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1749 "WLAT (R[n], DSP_R (m));",
1751 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1752 "WWAT (R[n], DSP_R (m) >> 16);",
1753 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1756 " iword &= 0xfd53; goto top;",
1759 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1760 "WLAT (R[n], DSP_R (m));",
1761 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1763 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1764 "WWAT (R[n], DSP_R (m) >> 16);",
1765 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1768 " iword &= 0xfd53; goto top;",
1771 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1772 "WLAT (R[n], DSP_R (m));",
1773 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1775 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1776 "DSP_R (m) = RSWAT (R[n]) << 16;",
1778 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1779 "DSP_R (m) = RSWAT (R[n]) << 16;",
1780 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1782 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1783 "DSP_R (m) = RSWAT (R[n]) << 16;",
1784 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1786 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1787 "WWAT (R[n], DSP_R (m) >> 16);",
1789 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1790 "WWAT (R[n], DSP_R (m) >> 16);",
1791 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1793 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1794 "WWAT (R[n], DSP_R (m) >> 16);",
1795 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1797 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1798 "DSP_R (m) = RLAT (R[n]);",
1800 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1801 "DSP_R (m) = RLAT (R[n]);",
1802 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1804 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1805 "DSP_R (m) = RLAT (R[n]);",
1806 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1808 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1809 "WLAT (R[n], DSP_R (m));",
1811 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1812 "WLAT (R[n], DSP_R (m));",
1813 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1815 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1816 "WLAT (R[n], DSP_R (m));",
1817 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1819 { "", "", "nopx nopy", "1111000000000000",
1822 { "", "", "ppi", "1111100000000000",
1823 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1824 "ppi_insn (RIAT (nip));",
1825 "SET_NIP (nip + 2);",
1826 "iword &= 0xf7ff; goto top;",
1833 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1834 "int Sz = DSP_R (z) & 0xffff0000;",
1838 "else if (i >= 128 - 16)",
1839 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1842 " RAISE_EXCEPTION (SIGILL);",
1845 "res &= 0xffff0000;",
1849 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1850 "int Sz = DSP_R (z);",
1851 "int Sz_grd = GET_DSP_GRD (z);",
1863 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1865 " res_grd = SEXT (res_grd);",
1866 " carry = res_grd & 1;",
1868 "else if (i >= 96)",
1873 " res_grd = SIGN32 (Sz_grd);",
1878 " res = Sz >> i | Sz_grd << 32 - i;",
1879 " res_grd = Sz_grd >> i;",
1881 " carry = Sz >> (i - 1) & 1;",
1885 " RAISE_EXCEPTION (SIGILL);",
1888 "COMPUTE_OVERFLOW;",
1889 "greater_equal = 0;",
1891 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1892 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1893 "if (res == 0x80000000)",
1894 " res = 0x7fffffff;",
1896 "DSP_GRD (g) = SIGN32 (res);",
1899 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1900 "int Sx = DSP_R (x);",
1901 "int Sx_grd = GET_DSP_GRD (x);",
1902 "int Sy = DSP_R (y);",
1903 "int Sy_grd = SIGN32 (Sy);",
1905 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1906 "if (res == 0x80000000)",
1907 " res = 0x7fffffff;",
1909 "DSP_GRD (g) = SIGN32 (res);",
1913 "carry = (unsigned) res > (unsigned) Sx;",
1914 "res_grd = Sx_grd - Sy_grd - carry;",
1915 "COMPUTE_OVERFLOW;",
1918 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1919 "int Sx = DSP_R (x);",
1920 "int Sx_grd = GET_DSP_GRD (x);",
1921 "int Sy = DSP_R (y);",
1922 "int Sy_grd = SIGN32 (Sy);",
1924 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1925 "if (res == 0x80000000)",
1926 " res = 0x7fffffff;",
1928 "DSP_GRD (g) = SIGN32 (res);",
1932 "carry = (unsigned) res < (unsigned) Sx;",
1933 "res_grd = Sx_grd + Sy_grd + carry;",
1934 "COMPUTE_OVERFLOW;",
1936 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1937 "int Sx = DSP_R (x);",
1938 "int Sx_grd = GET_DSP_GRD (x);",
1939 "int Sy = DSP_R (y);",
1940 "int Sy_grd = SIGN32 (Sy);",
1942 "res = Sx - Sy - (DSR & 1);",
1943 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1944 "res_grd = Sx_grd + Sy_grd + carry;",
1945 "COMPUTE_OVERFLOW;",
1948 "if (res || res_grd)\n",
1949 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1951 " DSR |= DSR_MASK_Z | overflow;\n",
1955 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1956 "int Sx = DSP_R (x);",
1957 "int Sx_grd = GET_DSP_GRD (x);",
1958 "int Sy = DSP_R (y);",
1959 "int Sy_grd = SIGN32 (Sy);",
1961 "res = Sx + Sy + (DSR & 1);",
1962 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1963 "res_grd = Sx_grd + Sy_grd + carry;",
1964 "COMPUTE_OVERFLOW;",
1967 "if (res || res_grd)\n",
1968 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1970 " DSR |= DSR_MASK_Z | overflow;\n",
1974 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1975 "int Sx = DSP_R (x);",
1976 "int Sx_grd = GET_DSP_GRD (x);",
1977 "int Sy = DSP_R (y);",
1978 "int Sy_grd = SIGN32 (Sy);",
1980 "z = 17; /* Ignore result. */",
1982 "carry = (unsigned) res > (unsigned) Sx;",
1983 "res_grd = Sx_grd - Sy_grd - carry;",
1984 "COMPUTE_OVERFLOW;",
1987 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1989 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1991 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
1992 "/* FIXME: duplicate code pabs. */",
1994 "res_grd = GET_DSP_GRD (x);",
2000 " carry = (res != 0); /* The manual has a bug here. */",
2001 " res_grd = -res_grd - carry;",
2003 "COMPUTE_OVERFLOW;",
2004 "/* ??? The re-computing of overflow after",
2005 " saturation processing is specific to pabs. */",
2006 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2009 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2011 "res_grd = GET_DSP_GRD (x);",
2017 " carry = (res != 0); /* The manual has a bug here. */",
2018 " res_grd = -res_grd - carry;",
2020 "COMPUTE_OVERFLOW;",
2021 "/* ??? The re-computing of overflow after",
2022 " saturation processing is specific to pabs. */",
2023 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2027 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2028 "/* FIXME: duplicate code prnd. */",
2029 "int Sx = DSP_R (x);",
2030 "int Sx_grd = GET_DSP_GRD (x);",
2032 "res = (Sx + 0x8000) & 0xffff0000;",
2033 "carry = (unsigned) res < (unsigned) Sx;",
2034 "res_grd = Sx_grd + carry;",
2035 "COMPUTE_OVERFLOW;",
2038 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2039 "int Sx = DSP_R (x);",
2040 "int Sx_grd = GET_DSP_GRD (x);",
2042 "res = (Sx + 0x8000) & 0xffff0000;",
2043 "carry = (unsigned) res < (unsigned) Sx;",
2044 "res_grd = Sx_grd + carry;",
2045 "COMPUTE_OVERFLOW;",
2049 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2050 "/* FIXME: duplicate code pabs. */",
2054 "greater_equal = DSR_MASK_G;",
2064 " res = 0x7fffffff;",
2067 " overflow = DSR_MASK_V;",
2068 " greater_equal = 0;",
2073 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2077 "greater_equal = DSR_MASK_G;",
2087 " res = 0x7fffffff;",
2090 " overflow = DSR_MASK_V;",
2091 " greater_equal = 0;",
2096 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2097 "/* FIXME: duplicate code prnd. */",
2098 "int Sy = DSP_R (y);",
2099 "int Sy_grd = SIGN32 (Sy);",
2101 "res = (Sy + 0x8000) & 0xffff0000;",
2102 "carry = (unsigned) res < (unsigned) Sy;",
2103 "res_grd = Sy_grd + carry;",
2104 "COMPUTE_OVERFLOW;",
2107 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2108 "int Sy = DSP_R (y);",
2109 "int Sy_grd = SIGN32 (Sy);",
2111 "res = (Sy + 0x8000) & 0xffff0000;",
2112 "carry = (unsigned) res < (unsigned) Sy;",
2113 "res_grd = Sy_grd + carry;",
2114 "COMPUTE_OVERFLOW;",
2117 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2118 "int Sx = DSP_R (x) & 0xffff0000;",
2119 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2123 "else if (Sy >= 128 - 16)",
2124 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2127 " RAISE_EXCEPTION (SIGILL);",
2130 "goto cond_logical;",
2132 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2133 "int Sx = DSP_R (x);",
2134 "int Sx_grd = GET_DSP_GRD (x);",
2135 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2147 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2149 " res_grd = SEXT (res_grd);",
2150 " carry = res_grd & 1;",
2152 "else if (Sy >= 96)",
2157 " res_grd = SIGN32 (Sx_grd);",
2162 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
2163 " res_grd = Sx_grd >> Sy;",
2165 " carry = Sx >> (Sy - 1) & 1;",
2169 " RAISE_EXCEPTION (SIGILL);",
2172 "COMPUTE_OVERFLOW;",
2173 "greater_equal = 0;",
2175 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2176 "int Sx = DSP_R (x);",
2177 "int Sx_grd = GET_DSP_GRD (x);",
2178 "int Sy = DSP_R (y);",
2179 "int Sy_grd = SIGN32 (Sy);",
2182 "carry = (unsigned) res > (unsigned) Sx;",
2183 "res_grd = Sx_grd - Sy_grd - carry;",
2184 "COMPUTE_OVERFLOW;",
2187 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2188 "int Sx = DSP_R (x);",
2189 "int Sx_grd = GET_DSP_GRD (x);",
2190 "int Sy = DSP_R (y);",
2191 "int Sy_grd = SIGN32 (Sy);",
2194 "carry = (unsigned) res > (unsigned) Sy;",
2195 "res_grd = Sy_grd - Sx_grd - carry;",
2196 "COMPUTE_OVERFLOW;",
2199 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2200 "int Sx = DSP_R (x);",
2201 "int Sx_grd = GET_DSP_GRD (x);",
2202 "int Sy = DSP_R (y);",
2203 "int Sy_grd = SIGN32 (Sy);",
2206 "carry = (unsigned) res < (unsigned) Sx;",
2207 "res_grd = Sx_grd + Sy_grd + carry;",
2208 "COMPUTE_OVERFLOW;",
2211 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2212 "res = DSP_R (x) & DSP_R (y);",
2214 "res &= 0xffff0000;",
2216 "if (iword & 0x200)\n",
2217 " goto assign_z;\n",
2221 "greater_equal = 0;",
2224 " DSR |= res >> 26 & DSR_MASK_N;\n",
2226 " DSR |= DSR_MASK_Z;\n",
2227 "goto assign_dc;\n",
2229 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2230 "res = DSP_R (x) ^ DSP_R (y);",
2231 "goto cond_logical;",
2233 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2234 "res = DSP_R (x) | DSP_R (y);",
2235 "goto cond_logical;",
2237 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2238 "int Sx = DSP_R (x);",
2239 "int Sx_grd = GET_DSP_GRD (x);",
2241 "res = Sx - 0x10000;",
2242 "carry = res > Sx;",
2243 "res_grd = Sx_grd - carry;",
2244 "COMPUTE_OVERFLOW;",
2246 "res &= 0xffff0000;",
2248 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2249 "int Sx = DSP_R (x);",
2250 "int Sx_grd = GET_DSP_GRD (x);",
2252 "res = Sx + 0x10000;",
2253 "carry = res < Sx;",
2254 "res_grd = Sx_grd + carry;",
2255 "COMPUTE_OVERFLOW;",
2257 "res &= 0xffff0000;",
2259 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2260 "int Sy = DSP_R (y);",
2261 "int Sy_grd = SIGN32 (Sy);",
2263 "res = Sy - 0x10000;",
2264 "carry = res > Sy;",
2265 "res_grd = Sy_grd - carry;",
2266 "COMPUTE_OVERFLOW;",
2268 "res &= 0xffff0000;",
2270 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2271 "int Sy = DSP_R (y);",
2272 "int Sy_grd = SIGN32 (Sy);",
2274 "res = Sy + 0x10000;",
2275 "carry = res < Sy;",
2276 "res_grd = Sy_grd + carry;",
2277 "COMPUTE_OVERFLOW;",
2279 "res &= 0xffff0000;",
2281 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2286 "greater_equal = 1;",
2288 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2289 "/* Do multiply. */",
2290 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2291 "if (res == 0x80000000)",
2292 " res = 0x7fffffff;",
2294 "DSP_GRD (g) = SIGN32 (res);",
2295 "/* FIXME: update DSR based on results of multiply! */",
2303 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2304 "unsigned Sx = DSP_R (x);",
2305 "int Sx_grd = GET_DSP_GRD (x);",
2310 " Sx_grd = ~Sx_grd;",
2324 " if (Sx & ~0 << i)",
2332 "res_grd = SIGN32 (res);",
2337 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2338 "unsigned Sy = DSP_R (y);",
2347 " if (Sy & ~0 << i)",
2355 "res_grd = SIGN32 (res);",
2360 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2361 "int Sx = DSP_R (x);",
2362 "int Sx_grd = GET_DSP_GRD (x);",
2365 "carry = res != 0;",
2366 "res_grd = 0 - Sx_grd - carry;",
2367 "COMPUTE_OVERFLOW;",
2370 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2372 "res_grd = GET_DSP_GRD (x);",
2374 "COMPUTE_OVERFLOW;",
2377 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2378 "int Sy = DSP_R (y);",
2379 "int Sy_grd = SIGN32 (Sy);",
2382 "carry = res != 0;",
2383 "res_grd = 0 - Sy_grd - carry;",
2384 "COMPUTE_OVERFLOW;",
2387 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2389 "res_grd = SIGN32 (res);",
2391 "COMPUTE_OVERFLOW;",
2394 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2396 "res_grd = SIGN32 (res);",
2399 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2401 "res_grd = SIGN32 (res);",
2404 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2405 "if (0xa05f >> z & 1)",
2406 " RAISE_EXCEPTION (SIGILL);",
2408 " MACH = DSP_R (z);",
2411 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2412 "if (0xa05f >> z & 1)",
2413 " RAISE_EXCEPTION (SIGILL);",
2415 " MACL = DSP_R (z) = res;",
2419 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2420 "int Sx = DSP_R (x);",
2422 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2423 "res_grd = GET_DSP_GRD (x);",
2426 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2429 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2430 "int Sy = DSP_R (y);",
2432 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2433 "res_grd = SIGN32 (Sy);",
2436 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2442 /* Tables of things to put into enums for sh-opc.h */
2443 static char *nibble_type_list
[] =
2478 char *arg_type_list
[] =
2512 make_enum_list (name
, s
)
2517 printf ("typedef enum {\n");
2520 printf ("\t%s,\n", *s
);
2524 printf ("} %s;\n", name
);
2536 memcpy (bufa
, a
->code
, 4);
2537 memcpy (bufa
+ 4, a
->code
+ 12, 4);
2540 memcpy (bufb
, b
->code
, 4);
2541 memcpy (bufb
+ 4, b
->code
+ 12, 4);
2543 diff
= strcmp (bufa
, bufb
);
2544 /* Stabilize the sort, so that later entries can override more general
2545 preceding entries. */
2546 return diff
? diff
: a
- b
;
2560 qsort (tab
, len
, sizeof (*p
), qfunc
);
2568 for (p
= tab
; p
->name
; p
++)
2570 printf ("%s %-30s\n", p
->code
, p
->name
);
2574 static unsigned short table
[1 << 16];
2576 static int warn_conflicts
= 0;
2579 conflict_warn (val
, i
)
2586 fprintf (stderr
, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2587 val
, i
, table
[val
]);
2589 for (ix
= sizeof (tab
) / sizeof (tab
[0]); ix
>= 0; ix
--)
2590 if (tab
[ix
].index
== i
|| tab
[ix
].index
== j
)
2592 key
= ((tab
[ix
].code
[0] - '0') << 3) +
2593 ((tab
[ix
].code
[1] - '0') << 2) +
2594 ((tab
[ix
].code
[2] - '0') << 1) +
2595 ((tab
[ix
].code
[3] - '0'));
2597 if (val
>> 12 == key
)
2598 fprintf (stderr
, " %s -- %s\n", tab
[ix
].code
, tab
[ix
].name
);
2601 for (ix
= sizeof (movsxy_tab
) / sizeof (movsxy_tab
[0]); ix
>= 0; ix
--)
2602 if (movsxy_tab
[ix
].index
== i
|| movsxy_tab
[ix
].index
== j
)
2604 key
= ((movsxy_tab
[ix
].code
[0] - '0') << 3) +
2605 ((movsxy_tab
[ix
].code
[1] - '0') << 2) +
2606 ((movsxy_tab
[ix
].code
[2] - '0') << 1) +
2607 ((movsxy_tab
[ix
].code
[3] - '0'));
2609 if (val
>> 12 == key
)
2610 fprintf (stderr
, " %s -- %s\n",
2611 movsxy_tab
[ix
].code
, movsxy_tab
[ix
].name
);
2614 for (ix
= sizeof (ppi_tab
) / sizeof (ppi_tab
[0]); ix
>= 0; ix
--)
2615 if (ppi_tab
[ix
].index
== i
|| ppi_tab
[ix
].index
== j
)
2617 key
= ((ppi_tab
[ix
].code
[0] - '0') << 3) +
2618 ((ppi_tab
[ix
].code
[1] - '0') << 2) +
2619 ((ppi_tab
[ix
].code
[2] - '0') << 1) +
2620 ((ppi_tab
[ix
].code
[3] - '0'));
2622 if (val
>> 12 == key
)
2623 fprintf (stderr
, " %s -- %s\n",
2624 ppi_tab
[ix
].code
, ppi_tab
[ix
].name
);
2628 /* Take an opcode, expand all varying fields in it out and fill all the
2629 right entries in 'table' with the opcode index. */
2632 expand_opcode (val
, i
, s
)
2639 if (warn_conflicts
&& table
[val
] != 0)
2640 conflict_warn (val
, i
);
2650 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
2654 /* Consume an arbitrary number of ones and zeros. */
2656 j
= (j
<< 1) + (s
[m
++] - '0');
2657 } while (s
[m
] == '0' || s
[m
] == '1');
2658 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
2660 case 'N': /* NN -- four-way fork */
2661 for (j
= 0; j
< 4; j
++)
2662 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2664 case 'x': /* xx or xy -- two-way or four-way fork */
2665 for (j
= 0; j
< 4; j
+= (s
[1] == 'x' ? 2 : 1))
2666 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2668 case 'y': /* yy or yx -- two-way or four-way fork */
2669 for (j
= 0; j
< (s
[1] == 'x' ? 4 : 2); j
++)
2670 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2672 case '?': /* Seven-way "wildcard" fork for movxy */
2673 expand_opcode ((val
<< 2), i
, s
+ 2);
2674 for (j
= 1; j
< 4; j
++)
2676 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2677 expand_opcode ((val
<< 2) | (j
+ 16), i
, s
+ 2);
2680 case 'i': /* eg. "i8*1" */
2681 case '.': /* "...." is a wildcard */
2684 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2685 for (j
= 0; j
< 16; j
++)
2686 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2689 /* eeee -- even numbered register:
2691 for (j
= 0; j
< 15; j
+= 2)
2692 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2695 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2696 MMMM -- 10-way fork */
2697 expand_opcode ((val
<< 4) | 5, i
, s
+ 4);
2698 for (j
= 7; j
< 16; j
++)
2699 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2703 GGGG -- two-way fork */
2704 for (j
= 13; j
<= 15; j
+=2)
2705 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2708 /* ssss -- 10-way fork */
2709 /* System registers mach, macl, pr: */
2710 for (j
= 0; j
< 3; j
++)
2711 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2712 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2713 for (j
= 5; j
< 12; j
++)
2714 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2717 /* XX/XY -- 2/4 way fork. */
2718 for (j
= 0; j
< 4; j
+= (s
[1] == 'X' ? 2 : 1))
2719 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2722 /* aa/ax -- 2/4 way fork. */
2723 for (j
= 0; j
< 4; j
+= (s
[1] == 'a' ? 2 : 1))
2724 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2727 /* YY/YX -- 2/4 way fork. */
2728 for (j
= 0; j
< (s
[1] == 'Y' ? 2 : 4); j
+= 1)
2729 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2732 /* AA/AY: 2/4 way fork. */
2733 for (j
= 0; j
< (s
[1] == 'A' ? 2 : 4); j
+= 1)
2734 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2737 /* vv(VV) -- 4(16) way fork. */
2738 /* Vector register fv0/4/8/12. */
2741 /* 2 vector registers. */
2742 for (j
= 0; j
< 15; j
++)
2743 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2747 /* 1 vector register. */
2748 for (j
= 0; j
< 4; j
+= 1)
2749 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2756 /* Print the jump table used to index an opcode into a switch
2760 dumptable (name
, size
, start
)
2770 printf ("unsigned short %s[%d]={\n", name
, size
);
2771 while (i
< start
+ size
)
2775 printf ("/* 0x%x */\n", i
);
2782 printf ("%2d", table
[i
+ j
+ k
]);
2801 static int index
= 1;
2804 for (; p
->name
; p
++)
2807 expand_opcode (0, p
->index
, p
->code
);
2811 /* Table already contains all the switch case tags for 16-bit opcode double
2812 data transfer (ddt) insns, and the switch case tag for processing parallel
2813 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2814 latter tag to represent all combinations of ppi with ddt. */
2820 for (i
= 0xf000; i
< 0xf400; i
++)
2822 table
[i
+ 0x800] = table
[0xf800];
2829 for (; p
->name
; p
++)
2838 printf (" /* %s %s */\n", p
->name
, p
->code
);
2839 printf (" case %d: \n", p
->index
);
2847 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2852 /* Wildcard expansion, nothing to do here. */
2856 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2860 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2872 printf (" int n = (iword >> 8) & 0xf;\n");
2877 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2881 if (s
[1] == 'y') /* xy */
2883 printf (" int n = (iword & 3) ? \n");
2884 printf (" ((iword >> 9) & 1) + 4 : \n");
2885 printf (" REG_xy ((iword >> 8) & 3);\n");
2888 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2893 if (s
[1] == 'x') /* yx */
2895 printf (" int n = (iword & 0xc) ? \n");
2896 printf (" ((iword >> 8) & 1) + 6 : \n");
2897 printf (" REG_yx ((iword >> 8) & 3);\n");
2900 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2909 printf (" int m = (iword >> 4) & 0xf;\n");
2913 if (s
[1] == 'Y') /* XY */
2915 printf (" int m = (iword & 3) ? \n");
2916 printf (" ((iword >> 7) & 1) + 8 : \n");
2917 printf (" DSP_xy ((iword >> 6) & 3);\n");
2920 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2924 if (s
[1] == 'x') /* ax */
2926 printf (" int m = (iword & 3) ? \n");
2927 printf (" 7 - ((iword >> 6) & 2) : \n");
2928 printf (" DSP_ax ((iword >> 6) & 3);\n");
2931 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2935 if (s
[1] == 'X') /* YX */
2937 printf (" int m = (iword & 0xc) ? \n");
2938 printf (" ((iword >> 6) & 1) + 10 : \n");
2939 printf (" DSP_yx ((iword >> 6) & 3);\n");
2942 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2946 if (s
[1] == 'Y') /* AY */
2948 printf (" int m = (iword & 0xc) ? \n");
2949 printf (" 7 - ((iword >> 5) & 2) : \n");
2950 printf (" DSP_ay ((iword >> 6) & 3);\n");
2953 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2958 printf (" int i = (iword & 0x");
2964 "gensim_caselist: Unknown char '%c' in %s\n",
2985 "gensim_caselist: Unknown char '%c' in %s\n",
2989 case '.': /* eg. "i12." */
3006 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3007 sextbit
- 1, sextbit
- 1);
3011 printf (" TB (m,n);\n");
3013 printf (" TL (m);\n");
3015 printf (" TL (n);\n");
3020 for (r
= p
->refs
; *r
; r
++)
3022 if (*r
== 'f') printf (" CREF (15);\n");
3026 printf (" int i = n;\n");
3028 printf (" CREF (i);\n");
3029 printf (" } while (i-- > 0);\n");
3035 printf (" int i = n;\n");
3037 printf (" CREF (i);\n");
3038 printf (" } while (i++ < 14);\n");
3041 if (*r
== '0') printf (" CREF (0);\n");
3042 if (*r
== '8') printf (" CREF (8);\n");
3043 if (*r
== '9') printf (" CREF (9);\n");
3044 if (*r
== 'n') printf (" CREF (n);\n");
3045 if (*r
== 'm') printf (" CREF (m);\n");
3050 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3054 printf (" %s\n", p
->stuff
[j
]);
3062 for (r
= p
->defs
; *r
; r
++)
3064 if (*r
== 'f') printf (" CDEF (15);\n");
3068 printf (" int i = n;\n");
3070 printf (" CDEF (i);\n");
3071 printf (" } while (i-- > 0);\n");
3077 printf (" int i = n;\n");
3079 printf (" CDEF (i);\n");
3080 printf (" } while (i++ < 14);\n");
3083 if (*r
== '0') printf (" CDEF (0);\n");
3084 if (*r
== 'n') printf (" CDEF (n);\n");
3085 if (*r
== 'm') printf (" CDEF (m);\n");
3089 printf (" break;\n");
3098 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3099 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3100 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3101 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3102 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3103 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3104 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3105 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3106 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3107 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3108 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3109 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3110 printf (" switch (jump_table[iword]) {\n");
3112 gensim_caselist (tab
);
3113 gensim_caselist (movsxy_tab
);
3115 printf (" default:\n");
3117 printf (" RAISE_EXCEPTION (SIGILL);\n");
3128 for (p
= tab
; p
->name
; p
++)
3131 printf ("#define OPC_");
3145 printf (" %d\n",p
->index
);
3149 static int ppi_index
;
3151 /* Take a ppi code, expand all varying fields in it and fill all the
3152 right entries in 'table' with the opcode index.
3153 NOTE: tail recursion optimization removed for simplicity. */
3156 expand_ppi_code (val
, i
, s
)
3166 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n", s
[0]);
3171 if (warn_conflicts
&& table
[val
] != 0)
3172 conflict_warn (val
, i
);
3174 /* The last four bits are disregarded for the switch table. */
3178 /* Four-bit expansion. */
3179 for (j
= 0; j
< 16; j
++)
3180 expand_ppi_code ((val
<< 4) + j
, i
, s
+ 4);
3184 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3187 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3192 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3193 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3196 expand_ppi_code ((val
<< 2) + 1, ppi_index
++, s
+ 2);
3197 expand_ppi_code ((val
<< 2) + 2, i
, s
+ 2);
3198 expand_ppi_code ((val
<< 2) + 3, i
, s
+ 2);
3209 for (p
= ppi_tab
; p
->name
; p
++)
3211 p
->index
= ppi_index
++;
3212 expand_ppi_code (0, p
->index
, p
->code
);
3221 printf ("#define DSR_MASK_G 0x80\n");
3222 printf ("#define DSR_MASK_Z 0x40\n");
3223 printf ("#define DSR_MASK_N 0x20\n");
3224 printf ("#define DSR_MASK_V 0x10\n");
3226 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3227 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3228 printf (" if (overflow && S) \\\n");
3230 printf (" if (res_grd & 0x80) \\\n");
3232 printf (" res = 0x80000000; \\\n");
3233 printf (" res_grd |= 0xff; \\\n");
3235 printf (" else \\\n");
3237 printf (" res = 0x7fffffff; \\\n");
3238 printf (" res_grd &= ~0xff; \\\n");
3240 printf (" overflow = 0; \\\n");
3242 printf ("} while (0)\n");
3244 printf ("#define ADD_SUB_GE \\\n");
3245 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3247 printf ("static void\n");
3248 printf ("ppi_insn (iword)\n");
3249 printf (" int iword;\n");
3251 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3252 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
3253 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3254 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
3255 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3256 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
3257 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3258 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
3259 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3260 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
3261 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3262 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
3264 printf (" int z;\n");
3265 printf (" int res, res_grd;\n");
3266 printf (" int carry, overflow, greater_equal;\n");
3268 printf (" switch (ppi_table[iword >> 4]) {\n");
3270 for (; p
->name
; p
++)
3278 printf (" /* %s %s */\n", p
->name
, p
->code
);
3279 printf (" case %d: \n", p
->index
);
3282 for (shift
= 16; *s
; )
3287 printf (" int i = (iword >> 4) & 0x7f;\n");
3297 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3303 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3304 printf ("\treturn;\n");
3306 printf (" case %d: \n", p
->index
+ 1);
3318 printf (" z = iword & 0xf;\n");
3326 else if (havedecl
== 2)
3328 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3333 (havedecl
== 2 ? " " : ""),
3341 printf (" if (iword & 0x200)\n");
3342 printf (" goto assign_z;\n");
3344 printf (" break;\n");
3348 printf (" default:\n");
3350 printf (" RAISE_EXCEPTION (SIGILL);\n");
3351 printf (" return;\n");
3354 printf (" DSR &= ~0xf1;\n");
3355 printf (" if (res || res_grd)\n");
3356 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3358 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3359 printf (" assign_dc:\n");
3360 printf (" switch (DSR >> 1 & 7)\n");
3362 printf (" case 0: /* Carry Mode */\n");
3363 printf (" DSR |= carry;\n");
3364 printf (" case 1: /* Negative Value Mode */\n");
3365 printf (" DSR |= res_grd >> 7 & 1;\n");
3366 printf (" case 2: /* Zero Value Mode */\n");
3367 printf (" DSR |= DSR >> 6 & 1;\n");
3368 printf (" case 3: /* Overflow mode\n");
3369 printf (" DSR |= overflow >> 4;\n");
3370 printf (" case 4: /* Signed Greater Than Mode */\n");
3371 printf (" DSR |= DSR >> 7 & 1;\n");
3372 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
3373 printf (" DSR |= greater_equal >> 7;\n");
3375 printf (" assign_z:\n");
3376 printf (" if (0xa05f >> z & 1)\n");
3378 printf (" RAISE_EXCEPTION (SIGILL);\n");
3379 printf (" return;\n");
3381 printf (" DSP_R (z) = res;\n");
3382 printf (" DSP_GRD (z) = res_grd;\n");
3391 /* Verify the table before anything else. */
3394 for (p
= tab
; p
->name
; p
++)
3396 /* Check that the code field contains 16 bits. */
3397 if (strlen (p
->code
) != 16)
3399 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
3400 p
->code
, strlen (p
->code
), p
->name
);
3406 /* Now generate the requested data. */
3409 if (ac
> 2 && strcmp (av
[2], "-w") == 0)
3413 if (strcmp (av
[1], "-t") == 0)
3417 else if (strcmp (av
[1], "-d") == 0)
3421 else if (strcmp (av
[1], "-s") == 0)
3424 dumptable ("sh_jump_table", 1 << 16, 0);
3426 memset (table
, 0, sizeof table
);
3427 filltable (movsxy_tab
);
3428 expand_ppi_movxy ();
3429 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3431 memset (table
, 0, sizeof table
);
3433 dumptable ("ppi_table", 1 << 12, 0);
3435 else if (strcmp (av
[1], "-x") == 0)
3438 filltable (movsxy_tab
);
3441 else if (strcmp (av
[1], "-p") == 0)
3448 fprintf (stderr
, "Opcode table generation no longer supported.\n");