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",
973 /* Allow for the case where m == n. */
979 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
984 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
986 "R[n] = RSBAT (R[m]);",
990 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
992 "R0 = RLAT (i + GBR);",
995 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
996 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
998 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
1001 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1003 "R[n] = RLAT (i + R[m]);",
1006 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1008 "R[n] = RLAT (R0 + R[m]);",
1011 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1013 "R[n] = RLAT (R[m]);",
1017 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1020 "R0 = RLAT (R[n]);",
1023 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1025 "R[n] = RLAT (R[m]);",
1028 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1030 "WLAT (i + GBR, R0);",
1032 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1034 "WLAT (i + R[n], R[m]);",
1036 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1038 "WLAT (R0 + R[n], R[m]);",
1040 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1041 /* Allow for the case where m == n. */
1047 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1052 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1054 "WLAT (R[n], R[m]);",
1057 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1059 "R0 = RSWAT (i + GBR);",
1062 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1063 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1065 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1068 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1070 "R0 = RSWAT (i + R[m]);",
1073 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1075 "R[n] = RSWAT (R0 + R[m]);",
1078 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1080 "R[n] = RSWAT (R[m]);",
1084 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1087 "R0 = RSWAT (R[n]);",
1090 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1092 "R[n] = RSWAT (R[m]);",
1095 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1097 "WWAT (i + GBR, R0);",
1099 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1101 "WWAT (i + R[m], R0);",
1103 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1105 "WWAT (R0 + R[n], R[m]);",
1107 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1108 /* Allow for the case where m == n. */
1114 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1119 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1121 "WWAT (R[n], R[m]);",
1124 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1125 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1126 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1129 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1130 "/* We don't simulate cache, so this insn is identical to mov. */",
1132 "WLAT (R[n], R[0]);",
1135 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1138 "/* if (T) R0 -> (Rn) */",
1140 " WLAT (R[n], R[0]);",
1145 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1149 "R[0] = RLAT (R[n]);",
1150 "/* if (interrupt/exception) 0 -> LDST */",
1151 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1154 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1157 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1160 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1162 "int e = target_little_endian ? 3 : 0;",
1164 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1165 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1168 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1170 "int e = target_little_endian ? 3 : 0;",
1172 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1173 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1177 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1178 "MACL = ((int) R[n]) * ((int) R[m]);",
1180 #if 0 /* FIXME: The above cast to int is not really portable.
1181 It should be replaced by a SEXT32 macro. */
1182 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1183 "MACL = R[n] * R[m];",
1187 /* muls.w - see muls */
1188 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1189 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1192 /* mulu.w - see mulu */
1193 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1194 "MACL = (((unsigned int) (unsigned short) R[n])",
1195 " * ((unsigned int) (unsigned short) R[m]));",
1198 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1202 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1204 "SET_SR_T (ult > 0);",
1205 "R[n] = ult - R[m];",
1206 "SET_SR_T (T || (R[n] > ult));",
1209 { "", "", "nop", "0000000000001001",
1213 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1218 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1219 "/* Except for the effect on the cache - which is not simulated -",
1220 " this is like a nop. */",
1223 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1224 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1225 "/* FIXME: Cache not implemented */",
1228 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1229 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1230 "/* FIXME: Cache not implemented */",
1233 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1234 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1235 "/* FIXME: Cache not implemented */",
1238 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1241 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1244 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1246 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1249 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1250 "/* Except for the effect on the cache - which is not simulated -",
1251 " this is like a nop. */",
1255 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1256 "/* Except for the effect on the cache - which is not simulated -",
1257 " this is like a nop. */",
1261 { "", "", "synco", "0000000010101011",
1262 "/* Except for the effect on the pipeline - which is not simulated -",
1263 " this is like a nop. */",
1266 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1268 "R[n] = (R[n] << 1) | T;",
1272 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1274 "R[n] = (UR[n] >> 1) | (T << 31);",
1278 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1279 "SET_SR_T (R[n] < 0);",
1284 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1285 "SET_SR_T (R[n] & 1);",
1286 "R[n] = UR[n] >> 1;",
1287 "R[n] |= (T << 31);",
1290 { "", "", "rte", "0000000000101011",
1294 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1296 "SET_SR (RLAT (R[15]) & 0x3f3);",
1298 "Delay_Slot (PC + 2);",
1300 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1302 "SET_NIP (PT2H (SPC));",
1304 "Delay_Slot (PC + 2);",
1308 { "", "", "rts", "0000000000001011",
1309 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1310 "SET_NIP (PT2H (PR));",
1312 "Delay_Slot (PC + 2);",
1314 { "", "", "rts/n", "0000000001101011",
1315 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1316 "SET_NIP (PT2H (PR));",
1318 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1319 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1322 "SET_NIP (PT2H (PR));",
1326 { "", "", "setdmx", "0000000010011000",
1327 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1328 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1332 { "", "", "setdmy", "0000000011001000",
1333 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1334 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1338 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1341 { "", "", "setrc #<imm>", "10000010i8*1....",
1342 /* It would be more realistic to let loop_start point to some static
1343 memory that contains an illegal opcode and then give a bus error when
1344 the loop is eventually encountered, but it seems not only simpler,
1345 but also more debugging-friendly to just catch the failure here. */
1346 "if (BUSERROR (RS | RE, maskw))",
1347 " RAISE_EXCEPTION (SIGILL);",
1350 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1351 " CHECK_INSN_PTR (insn_ptr);",
1355 { "", "", "sets", "0000000001011000",
1359 { "", "", "sett", "0000000000011000",
1363 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1364 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1367 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1368 "SET_SR_T (R[n] < 0);",
1372 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1373 "SET_SR_T (R[n] & 1);",
1374 "R[n] = R[n] >> 1;",
1377 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1378 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1381 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1382 "SET_SR_T (R[n] < 0);",
1386 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1389 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1392 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1396 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1397 "SET_SR_T (R[n] & 1);",
1398 "R[n] = UR[n] >> 1;",
1401 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1402 "R[n] = UR[n] >> 2;",
1404 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1405 "R[n] = UR[n] >> 8;",
1407 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1408 "R[n] = UR[n] >> 16;",
1411 { "", "", "sleep", "0000000000011011",
1412 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1415 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1419 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1421 " R[n] = SGR; /* priv mode */",
1423 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1425 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1427 " R[n] = DBR; /* priv mode */",
1429 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1431 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1432 "if (SR_MD)", /* FIXME? */
1433 " R[n] = TBR; /* priv mode */",
1435 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1437 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1440 "WLAT (R[n], CREG (m));",
1442 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1444 "{ /* priv mode */",
1447 " WLAT (R[n], SGR);",
1450 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1452 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1454 "{ /* priv mode */",
1457 " WLAT (R[n], DBR);",
1460 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1463 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1466 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1469 "WLAT (R[n], SREG (m));",
1472 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1476 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1478 "SET_SR_T (ult > R[n]);",
1479 "R[n] = ult - R[m];",
1480 "SET_SR_T (T || (R[n] > ult));",
1483 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1484 "ult = R[n] - R[m];",
1485 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1489 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1490 "R[n] = ((R[m] & 0xffff0000)",
1491 " | ((R[m] << 8) & 0xff00)",
1492 " | ((R[m] >> 8) & 0x00ff));",
1494 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1495 "R[n] = (((R[m] << 16) & 0xffff0000)",
1496 " | ((R[m] >> 16) & 0x00ffff));",
1499 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1501 "ult = RBAT (R[n]);",
1502 "SET_SR_T (ult == 0);",
1503 "WBAT (R[n],ult|0x80);",
1506 { "0", "", "trapa #<imm>", "11000011i8*1....",
1507 "long imm = 0xff & i;",
1508 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1509 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1510 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1515 " WLAT (R[15], GET_SR ());",
1517 " WLAT (R[15], PH2T (PC + 2));",
1519 "else if (!SR_BL) {",
1520 " SSR = GET_SR ();",
1521 " SPC = PH2T (PC + 2);",
1522 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1523 " /* FIXME: EXPEVT = 0x00000160; */",
1525 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1529 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1530 "SET_SR_T ((R[n] & R[m]) == 0);",
1532 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1533 "SET_SR_T ((R0 & i) == 0);",
1535 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1537 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1540 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1543 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1546 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1548 "ult = RBAT (GBR+R0);",
1550 "WBAT (GBR + R0, ult);",
1553 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1554 "R[n] = (((R[n] >> 16) & 0xffff)",
1555 " | ((R[m] << 16) & 0xffff0000));",
1559 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1560 "divl (0, R[n], R[m]);",
1562 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1563 "divl (0, R[n], R[m]);",
1571 /* If this is disabled, the simulator speeds up by about 12% on a
1572 450 MHz PIII - 9% with ACE_FAST.
1573 Maybe we should have separate simulator loops? */
1575 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1578 "DSP_R (m) = RSWAT (R[n]) << 16;",
1579 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1581 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1583 "DSP_R (m) = RSWAT (R[n]) << 16;",
1584 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1586 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1588 "DSP_R (m) = RSWAT (R[n]) << 16;",
1589 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1592 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1594 "DSP_R (m) = RSWAT (R[n]) << 16;",
1595 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1598 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1601 "DSP_R (m) = RSWAT (R[n]);",
1603 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1605 "DSP_R (m) = RSWAT (R[n]);",
1607 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1609 "DSP_R (m) = RSWAT (R[n]);",
1612 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1614 "DSP_R (m) = RSWAT (R[n]);",
1617 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1620 "WWAT (R[n], DSP_R (m) >> 16);",
1622 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1624 "WWAT (R[n], DSP_R (m) >> 16);",
1626 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1628 "WWAT (R[n], DSP_R (m) >> 16);",
1631 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1633 "WWAT (R[n], DSP_R (m) >> 16);",
1636 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1639 "WWAT (R[n], SEXT (DSP_R (m)));",
1641 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1643 "WWAT (R[n], SEXT (DSP_R (m)));",
1645 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1647 "WWAT (R[n], SEXT (DSP_R (m)));",
1650 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1652 "WWAT (R[n], SEXT (DSP_R (m)));",
1655 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1658 "DSP_R (m) = RLAT (R[n]);",
1659 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1661 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1663 "DSP_R (m) = RLAT (R[n]);",
1664 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1666 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1668 "DSP_R (m) = RLAT (R[n]);",
1669 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1672 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1674 "DSP_R (m) = RLAT (R[n]);",
1675 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1678 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1681 "WLAT (R[n], DSP_R (m));",
1683 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1685 "WLAT (R[n], DSP_R (m));",
1687 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1689 "WLAT (R[n], DSP_R (m));",
1692 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1694 "WLAT (R[n], DSP_R (m));",
1697 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1700 "WLAT (R[n], SEXT (DSP_R (m)));",
1702 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1704 "WLAT (R[n], SEXT (DSP_R (m)));",
1706 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1708 "WLAT (R[n], SEXT (DSP_R (m)));",
1711 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1713 "WLAT (R[n], SEXT (DSP_R (m)));",
1716 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1717 "DSP_R (m) = RSWAT (R[n]) << 16;",
1720 " iword &= 0xfd53; goto top;",
1723 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1724 "DSP_R (m) = RLAT (R[n]);",
1726 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1727 "DSP_R (m) = RSWAT (R[n]) << 16;",
1728 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1731 " iword &= 0xfd53; goto top;",
1734 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1735 "DSP_R (m) = RLAT (R[n]);",
1736 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1738 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1739 "DSP_R (m) = RSWAT (R[n]) << 16;",
1740 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1743 " iword &= 0xfd53; goto top;",
1746 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1747 "DSP_R (m) = RLAT (R[n]);",
1748 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1750 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1751 "WWAT (R[n], DSP_R (m) >> 16);",
1754 " iword &= 0xfd53; goto top;",
1757 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1758 "WLAT (R[n], DSP_R (m));",
1760 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1761 "WWAT (R[n], DSP_R (m) >> 16);",
1762 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1765 " iword &= 0xfd53; goto top;",
1768 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1769 "WLAT (R[n], DSP_R (m));",
1770 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1772 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1773 "WWAT (R[n], DSP_R (m) >> 16);",
1774 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1777 " iword &= 0xfd53; goto top;",
1780 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1781 "WLAT (R[n], DSP_R (m));",
1782 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1784 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1785 "DSP_R (m) = RSWAT (R[n]) << 16;",
1787 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1788 "DSP_R (m) = RSWAT (R[n]) << 16;",
1789 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1791 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1792 "DSP_R (m) = RSWAT (R[n]) << 16;",
1793 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1795 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1796 "WWAT (R[n], DSP_R (m) >> 16);",
1798 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1799 "WWAT (R[n], DSP_R (m) >> 16);",
1800 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1802 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1803 "WWAT (R[n], DSP_R (m) >> 16);",
1804 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1806 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1807 "DSP_R (m) = RLAT (R[n]);",
1809 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1810 "DSP_R (m) = RLAT (R[n]);",
1811 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1813 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1814 "DSP_R (m) = RLAT (R[n]);",
1815 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1817 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1818 "WLAT (R[n], DSP_R (m));",
1820 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1821 "WLAT (R[n], DSP_R (m));",
1822 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1824 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1825 "WLAT (R[n], DSP_R (m));",
1826 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1828 { "", "", "nopx nopy", "1111000000000000",
1831 { "", "", "ppi", "1111100000000000",
1832 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1833 "ppi_insn (RIAT (nip));",
1834 "SET_NIP (nip + 2);",
1835 "iword &= 0xf7ff; goto top;",
1842 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1843 "int Sz = DSP_R (z) & 0xffff0000;",
1847 "else if (i >= 128 - 16)",
1848 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1851 " RAISE_EXCEPTION (SIGILL);",
1854 "res &= 0xffff0000;",
1858 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1859 "int Sz = DSP_R (z);",
1860 "int Sz_grd = GET_DSP_GRD (z);",
1872 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1874 " res_grd = SEXT (res_grd);",
1875 " carry = res_grd & 1;",
1877 "else if (i >= 96)",
1882 " res_grd = SIGN32 (Sz_grd);",
1887 " res = Sz >> i | Sz_grd << 32 - i;",
1888 " res_grd = Sz_grd >> i;",
1890 " carry = Sz >> (i - 1) & 1;",
1894 " RAISE_EXCEPTION (SIGILL);",
1897 "COMPUTE_OVERFLOW;",
1898 "greater_equal = 0;",
1900 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1901 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1902 "if (res == 0x80000000)",
1903 " res = 0x7fffffff;",
1905 "DSP_GRD (g) = SIGN32 (res);",
1908 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1909 "int Sx = DSP_R (x);",
1910 "int Sx_grd = GET_DSP_GRD (x);",
1911 "int Sy = DSP_R (y);",
1912 "int Sy_grd = SIGN32 (Sy);",
1914 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1915 "if (res == 0x80000000)",
1916 " res = 0x7fffffff;",
1918 "DSP_GRD (g) = SIGN32 (res);",
1922 "carry = (unsigned) res > (unsigned) Sx;",
1923 "res_grd = Sx_grd - Sy_grd - carry;",
1924 "COMPUTE_OVERFLOW;",
1927 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1928 "int Sx = DSP_R (x);",
1929 "int Sx_grd = GET_DSP_GRD (x);",
1930 "int Sy = DSP_R (y);",
1931 "int Sy_grd = SIGN32 (Sy);",
1933 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1934 "if (res == 0x80000000)",
1935 " res = 0x7fffffff;",
1937 "DSP_GRD (g) = SIGN32 (res);",
1941 "carry = (unsigned) res < (unsigned) Sx;",
1942 "res_grd = Sx_grd + Sy_grd + carry;",
1943 "COMPUTE_OVERFLOW;",
1945 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1946 "int Sx = DSP_R (x);",
1947 "int Sx_grd = GET_DSP_GRD (x);",
1948 "int Sy = DSP_R (y);",
1949 "int Sy_grd = SIGN32 (Sy);",
1951 "res = Sx - Sy - (DSR & 1);",
1952 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1953 "res_grd = Sx_grd + Sy_grd + carry;",
1954 "COMPUTE_OVERFLOW;",
1957 "if (res || res_grd)\n",
1958 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1960 " DSR |= DSR_MASK_Z | overflow;\n",
1964 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1965 "int Sx = DSP_R (x);",
1966 "int Sx_grd = GET_DSP_GRD (x);",
1967 "int Sy = DSP_R (y);",
1968 "int Sy_grd = SIGN32 (Sy);",
1970 "res = Sx + Sy + (DSR & 1);",
1971 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1972 "res_grd = Sx_grd + Sy_grd + carry;",
1973 "COMPUTE_OVERFLOW;",
1976 "if (res || res_grd)\n",
1977 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1979 " DSR |= DSR_MASK_Z | overflow;\n",
1983 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1984 "int Sx = DSP_R (x);",
1985 "int Sx_grd = GET_DSP_GRD (x);",
1986 "int Sy = DSP_R (y);",
1987 "int Sy_grd = SIGN32 (Sy);",
1989 "z = 17; /* Ignore result. */",
1991 "carry = (unsigned) res > (unsigned) Sx;",
1992 "res_grd = Sx_grd - Sy_grd - carry;",
1993 "COMPUTE_OVERFLOW;",
1996 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1998 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
2000 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
2001 "/* FIXME: duplicate code pabs. */",
2003 "res_grd = GET_DSP_GRD (x);",
2009 " carry = (res != 0); /* The manual has a bug here. */",
2010 " res_grd = -res_grd - carry;",
2012 "COMPUTE_OVERFLOW;",
2013 "/* ??? The re-computing of overflow after",
2014 " saturation processing is specific to pabs. */",
2015 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2018 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2020 "res_grd = GET_DSP_GRD (x);",
2026 " carry = (res != 0); /* The manual has a bug here. */",
2027 " res_grd = -res_grd - carry;",
2029 "COMPUTE_OVERFLOW;",
2030 "/* ??? The re-computing of overflow after",
2031 " saturation processing is specific to pabs. */",
2032 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2036 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2037 "/* FIXME: duplicate code prnd. */",
2038 "int Sx = DSP_R (x);",
2039 "int Sx_grd = GET_DSP_GRD (x);",
2041 "res = (Sx + 0x8000) & 0xffff0000;",
2042 "carry = (unsigned) res < (unsigned) Sx;",
2043 "res_grd = Sx_grd + carry;",
2044 "COMPUTE_OVERFLOW;",
2047 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2048 "int Sx = DSP_R (x);",
2049 "int Sx_grd = GET_DSP_GRD (x);",
2051 "res = (Sx + 0x8000) & 0xffff0000;",
2052 "carry = (unsigned) res < (unsigned) Sx;",
2053 "res_grd = Sx_grd + carry;",
2054 "COMPUTE_OVERFLOW;",
2058 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2059 "/* FIXME: duplicate code pabs. */",
2063 "greater_equal = DSR_MASK_G;",
2073 " res = 0x7fffffff;",
2076 " overflow = DSR_MASK_V;",
2077 " greater_equal = 0;",
2082 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2086 "greater_equal = DSR_MASK_G;",
2096 " res = 0x7fffffff;",
2099 " overflow = DSR_MASK_V;",
2100 " greater_equal = 0;",
2105 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2106 "/* FIXME: duplicate code prnd. */",
2107 "int Sy = DSP_R (y);",
2108 "int Sy_grd = SIGN32 (Sy);",
2110 "res = (Sy + 0x8000) & 0xffff0000;",
2111 "carry = (unsigned) res < (unsigned) Sy;",
2112 "res_grd = Sy_grd + carry;",
2113 "COMPUTE_OVERFLOW;",
2116 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2117 "int Sy = DSP_R (y);",
2118 "int Sy_grd = SIGN32 (Sy);",
2120 "res = (Sy + 0x8000) & 0xffff0000;",
2121 "carry = (unsigned) res < (unsigned) Sy;",
2122 "res_grd = Sy_grd + carry;",
2123 "COMPUTE_OVERFLOW;",
2126 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2127 "int Sx = DSP_R (x) & 0xffff0000;",
2128 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2132 "else if (Sy >= 128 - 16)",
2133 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2136 " RAISE_EXCEPTION (SIGILL);",
2139 "goto cond_logical;",
2141 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2142 "int Sx = DSP_R (x);",
2143 "int Sx_grd = GET_DSP_GRD (x);",
2144 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2156 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2158 " res_grd = SEXT (res_grd);",
2159 " carry = res_grd & 1;",
2161 "else if (Sy >= 96)",
2166 " res_grd = SIGN32 (Sx_grd);",
2171 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
2172 " res_grd = Sx_grd >> Sy;",
2174 " carry = Sx >> (Sy - 1) & 1;",
2178 " RAISE_EXCEPTION (SIGILL);",
2181 "COMPUTE_OVERFLOW;",
2182 "greater_equal = 0;",
2184 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2185 "int Sx = DSP_R (x);",
2186 "int Sx_grd = GET_DSP_GRD (x);",
2187 "int Sy = DSP_R (y);",
2188 "int Sy_grd = SIGN32 (Sy);",
2191 "carry = (unsigned) res > (unsigned) Sx;",
2192 "res_grd = Sx_grd - Sy_grd - carry;",
2193 "COMPUTE_OVERFLOW;",
2196 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2197 "int Sx = DSP_R (x);",
2198 "int Sx_grd = GET_DSP_GRD (x);",
2199 "int Sy = DSP_R (y);",
2200 "int Sy_grd = SIGN32 (Sy);",
2203 "carry = (unsigned) res > (unsigned) Sy;",
2204 "res_grd = Sy_grd - Sx_grd - carry;",
2205 "COMPUTE_OVERFLOW;",
2208 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2209 "int Sx = DSP_R (x);",
2210 "int Sx_grd = GET_DSP_GRD (x);",
2211 "int Sy = DSP_R (y);",
2212 "int Sy_grd = SIGN32 (Sy);",
2215 "carry = (unsigned) res < (unsigned) Sx;",
2216 "res_grd = Sx_grd + Sy_grd + carry;",
2217 "COMPUTE_OVERFLOW;",
2220 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2221 "res = DSP_R (x) & DSP_R (y);",
2223 "res &= 0xffff0000;",
2225 "if (iword & 0x200)\n",
2226 " goto assign_z;\n",
2230 "greater_equal = 0;",
2233 " DSR |= res >> 26 & DSR_MASK_N;\n",
2235 " DSR |= DSR_MASK_Z;\n",
2236 "goto assign_dc;\n",
2238 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2239 "res = DSP_R (x) ^ DSP_R (y);",
2240 "goto cond_logical;",
2242 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2243 "res = DSP_R (x) | DSP_R (y);",
2244 "goto cond_logical;",
2246 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..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) pinc Sx,Dz", "100110ccxx..zzzz",
2258 "int Sx = DSP_R (x);",
2259 "int Sx_grd = GET_DSP_GRD (x);",
2261 "res = Sx + 0x10000;",
2262 "carry = res < Sx;",
2263 "res_grd = Sx_grd + carry;",
2264 "COMPUTE_OVERFLOW;",
2266 "res &= 0xffff0000;",
2268 { "","", "(if cc) pdec Sy,Dz", "101010cc..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) pinc Sy,Dz", "101110cc..yyzzzz",
2280 "int Sy = DSP_R (y);",
2281 "int Sy_grd = SIGN32 (Sy);",
2283 "res = Sy + 0x10000;",
2284 "carry = res < Sy;",
2285 "res_grd = Sy_grd + carry;",
2286 "COMPUTE_OVERFLOW;",
2288 "res &= 0xffff0000;",
2290 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2295 "greater_equal = 1;",
2297 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2298 "/* Do multiply. */",
2299 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2300 "if (res == 0x80000000)",
2301 " res = 0x7fffffff;",
2303 "DSP_GRD (g) = SIGN32 (res);",
2304 "/* FIXME: update DSR based on results of multiply! */",
2312 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2313 "unsigned Sx = DSP_R (x);",
2314 "int Sx_grd = GET_DSP_GRD (x);",
2319 " Sx_grd = ~Sx_grd;",
2333 " if (Sx & ~0 << i)",
2341 "res_grd = SIGN32 (res);",
2346 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2347 "unsigned Sy = DSP_R (y);",
2356 " if (Sy & ~0 << i)",
2364 "res_grd = SIGN32 (res);",
2369 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2370 "int Sx = DSP_R (x);",
2371 "int Sx_grd = GET_DSP_GRD (x);",
2374 "carry = res != 0;",
2375 "res_grd = 0 - Sx_grd - carry;",
2376 "COMPUTE_OVERFLOW;",
2379 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2381 "res_grd = GET_DSP_GRD (x);",
2383 "COMPUTE_OVERFLOW;",
2386 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2387 "int Sy = DSP_R (y);",
2388 "int Sy_grd = SIGN32 (Sy);",
2391 "carry = res != 0;",
2392 "res_grd = 0 - Sy_grd - carry;",
2393 "COMPUTE_OVERFLOW;",
2396 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2398 "res_grd = SIGN32 (res);",
2400 "COMPUTE_OVERFLOW;",
2403 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2405 "res_grd = SIGN32 (res);",
2408 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2410 "res_grd = SIGN32 (res);",
2413 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2414 "if (0xa05f >> z & 1)",
2415 " RAISE_EXCEPTION (SIGILL);",
2417 " MACH = DSP_R (z);",
2420 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2421 "if (0xa05f >> z & 1)",
2422 " RAISE_EXCEPTION (SIGILL);",
2424 " MACL = DSP_R (z) = res;",
2428 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2429 "int Sx = DSP_R (x);",
2431 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2432 "res_grd = GET_DSP_GRD (x);",
2435 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2438 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2439 "int Sy = DSP_R (y);",
2441 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2442 "res_grd = SIGN32 (Sy);",
2445 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2451 /* Tables of things to put into enums for sh-opc.h */
2452 static char *nibble_type_list[] =
2487 char *arg_type_list[] =
2521 make_enum_list (name, s)
2526 printf ("typedef enum {\n");
2529 printf ("\t%s,\n", *s);
2533 printf ("} %s;\n", name);
2545 memcpy (bufa, a->code, 4);
2546 memcpy (bufa + 4, a->code + 12, 4);
2549 memcpy (bufb, b->code, 4);
2550 memcpy (bufb + 4, b->code + 12, 4);
2552 diff = strcmp (bufa, bufb);
2553 /* Stabilize the sort, so that later entries can override more general
2554 preceding entries. */
2555 return diff ? diff : a - b;
2569 qsort (tab, len, sizeof (*p), qfunc);
2577 for (p = tab; p->name; p++)
2579 printf ("%s %-30s\n", p->code, p->name);
2583 static unsigned short table[1 << 16];
2585 static int warn_conflicts = 0;
2588 conflict_warn (val, i)
2595 fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2596 val, i, table[val]);
2598 for (ix = sizeof (tab) / sizeof (tab[0]); ix >= 0; ix--)
2599 if (tab[ix].index == i || tab[ix].index == j)
2601 key = ((tab[ix].code[0] - '0') << 3) +
2602 ((tab[ix].code[1] - '0') << 2) +
2603 ((tab[ix].code[2] - '0') << 1) +
2604 ((tab[ix].code[3] - '0'));
2606 if (val >> 12 == key)
2607 fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name);
2610 for (ix = sizeof (movsxy_tab) / sizeof (movsxy_tab[0]); ix >= 0; ix--)
2611 if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
2613 key = ((movsxy_tab[ix].code[0] - '0') << 3) +
2614 ((movsxy_tab[ix].code[1] - '0') << 2) +
2615 ((movsxy_tab[ix].code[2] - '0') << 1) +
2616 ((movsxy_tab[ix].code[3] - '0'));
2618 if (val >> 12 == key)
2619 fprintf (stderr, " %s -- %s\n",
2620 movsxy_tab[ix].code, movsxy_tab[ix].name);
2623 for (ix = sizeof (ppi_tab) / sizeof (ppi_tab[0]); ix >= 0; ix--)
2624 if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
2626 key = ((ppi_tab[ix].code[0] - '0') << 3) +
2627 ((ppi_tab[ix].code[1] - '0') << 2) +
2628 ((ppi_tab[ix].code[2] - '0') << 1) +
2629 ((ppi_tab[ix].code[3] - '0'));
2631 if (val >> 12 == key)
2632 fprintf (stderr, " %s -- %s\n",
2633 ppi_tab[ix].code, ppi_tab[ix].name);
2637 /* Take an opcode, expand all varying fields in it out and fill all the
2638 right entries in 'table' with the opcode index. */
2641 expand_opcode (val, i, s)
2648 if (warn_conflicts && table[val] != 0)
2649 conflict_warn (val, i);
2659 fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
2663 /* Consume an arbitrary number of ones and zeros. */
2665 j = (j << 1) + (s[m++] - '0');
2666 } while (s[m] == '0' || s[m] == '1');
2667 expand_opcode ((val << m) | j, i, s + m);
2669 case 'N': /* NN -- four-way fork */
2670 for (j = 0; j < 4; j++)
2671 expand_opcode ((val << 2) | j, i, s + 2);
2673 case 'x': /* xx or xy -- two-way or four-way fork */
2674 for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1))
2675 expand_opcode ((val << 2) | j, i, s + 2);
2677 case 'y': /* yy or yx -- two-way or four-way fork */
2678 for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++)
2679 expand_opcode ((val << 2) | j, i, s + 2);
2681 case '?': /* Seven-way "wildcard" fork for movxy */
2682 expand_opcode ((val << 2), i, s + 2);
2683 for (j = 1; j < 4; j++)
2685 expand_opcode ((val << 2) | j, i, s + 2);
2686 expand_opcode ((val << 2) | (j + 16), i, s + 2);
2689 case 'i': /* eg. "i8*1" */
2690 case '.': /* "...." is a wildcard */
2693 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2694 for (j = 0; j < 16; j++)
2695 expand_opcode ((val << 4) | j, i, s + 4);
2698 /* eeee -- even numbered register:
2700 for (j = 0; j < 15; j += 2)
2701 expand_opcode ((val << 4) | j, i, s + 4);
2704 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2705 MMMM -- 10-way fork */
2706 expand_opcode ((val << 4) | 5, i, s + 4);
2707 for (j = 7; j < 16; j++)
2708 expand_opcode ((val << 4) | j, i, s + 4);
2712 GGGG -- two-way fork */
2713 for (j = 13; j <= 15; j +=2)
2714 expand_opcode ((val << 4) | j, i, s + 4);
2717 /* ssss -- 10-way fork */
2718 /* System registers mach, macl, pr: */
2719 for (j = 0; j < 3; j++)
2720 expand_opcode ((val << 4) | j, i, s + 4);
2721 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2722 for (j = 5; j < 12; j++)
2723 expand_opcode ((val << 4) | j, i, s + 4);
2726 /* XX/XY -- 2/4 way fork. */
2727 for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1))
2728 expand_opcode ((val << 2) | j, i, s + 2);
2731 /* aa/ax -- 2/4 way fork. */
2732 for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1))
2733 expand_opcode ((val << 2) | j, i, s + 2);
2736 /* YY/YX -- 2/4 way fork. */
2737 for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1)
2738 expand_opcode ((val << 2) | j, i, s + 2);
2741 /* AA/AY: 2/4 way fork. */
2742 for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1)
2743 expand_opcode ((val << 2) | j, i, s + 2);
2746 /* vv(VV) -- 4(16) way fork. */
2747 /* Vector register fv0/4/8/12. */
2750 /* 2 vector registers. */
2751 for (j = 0; j < 15; j++)
2752 expand_opcode ((val << 4) | j, i, s + 4);
2756 /* 1 vector register. */
2757 for (j = 0; j < 4; j += 1)
2758 expand_opcode ((val << 2) | j, i, s + 2);
2765 /* Print the jump table used to index an opcode into a switch
2769 dumptable (name, size, start)
2779 printf ("unsigned short %s[%d]={\n", name, size);
2780 while (i < start + size)
2784 printf ("/* 0x%x */\n", i);
2791 printf ("%2d", table[i + j + k]);
2810 static int index = 1;
2813 for (; p->name; p++)
2816 expand_opcode (0, p->index, p->code);
2820 /* Table already contains all the switch case tags for 16-bit opcode double
2821 data transfer (ddt) insns, and the switch case tag for processing parallel
2822 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2823 latter tag to represent all combinations of ppi with ddt. */
2829 for (i = 0xf000; i < 0xf400; i++)
2831 table[i + 0x800] = table[0xf800];
2838 for (; p->name; p++)
2847 printf (" /* %s %s */\n", p->name, p->code);
2848 printf (" case %d: \n", p->index);
2856 fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2861 /* Wildcard expansion, nothing to do here. */
2865 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2869 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2881 printf (" int n = (iword >> 8) & 0xf;\n");
2886 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2890 if (s[1] == 'y') /* xy */
2892 printf (" int n = (iword & 3) ? \n");
2893 printf (" ((iword >> 9) & 1) + 4 : \n");
2894 printf (" REG_xy ((iword >> 8) & 3);\n");
2897 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2902 if (s[1] == 'x') /* yx */
2904 printf (" int n = (iword & 0xc) ? \n");
2905 printf (" ((iword >> 8) & 1) + 6 : \n");
2906 printf (" REG_yx ((iword >> 8) & 3);\n");
2909 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2918 printf (" int m = (iword >> 4) & 0xf;\n");
2922 if (s[1] == 'Y') /* XY */
2924 printf (" int m = (iword & 3) ? \n");
2925 printf (" ((iword >> 7) & 1) + 8 : \n");
2926 printf (" DSP_xy ((iword >> 6) & 3);\n");
2929 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2933 if (s[1] == 'x') /* ax */
2935 printf (" int m = (iword & 3) ? \n");
2936 printf (" 7 - ((iword >> 6) & 2) : \n");
2937 printf (" DSP_ax ((iword >> 6) & 3);\n");
2940 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2944 if (s[1] == 'X') /* YX */
2946 printf (" int m = (iword & 0xc) ? \n");
2947 printf (" ((iword >> 6) & 1) + 10 : \n");
2948 printf (" DSP_yx ((iword >> 6) & 3);\n");
2951 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2955 if (s[1] == 'Y') /* AY */
2957 printf (" int m = (iword & 0xc) ? \n");
2958 printf (" 7 - ((iword >> 5) & 2) : \n");
2959 printf (" DSP_ay ((iword >> 6) & 3);\n");
2962 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2967 printf (" int i = (iword & 0x");
2973 "gensim_caselist: Unknown char '%c' in %s\n",
2994 "gensim_caselist: Unknown char '%c' in %s\n",
2998 case '.': /* eg. "i12." */
3015 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3016 sextbit - 1, sextbit - 1);
3020 printf (" TB (m,n);\n");
3022 printf (" TL (m);\n");
3024 printf (" TL (n);\n");
3029 for (r = p->refs; *r; r++)
3031 if (*r == 'f') printf (" CREF (15);\n");
3035 printf (" int i = n;\n");
3037 printf (" CREF (i);\n");
3038 printf (" } while (i-- > 0);\n");
3044 printf (" int i = n;\n");
3046 printf (" CREF (i);\n");
3047 printf (" } while (i++ < 14);\n");
3050 if (*r == '0') printf (" CREF (0);\n");
3051 if (*r == '8') printf (" CREF (8);\n");
3052 if (*r == '9') printf (" CREF (9);\n");
3053 if (*r == 'n') printf (" CREF (n);\n");
3054 if (*r == 'm') printf (" CREF (m);\n");
3059 for (j = 0; j < MAX_NR_STUFF; j++)
3063 printf (" %s\n", p->stuff[j]);
3071 for (r = p->defs; *r; r++)
3073 if (*r == 'f') printf (" CDEF (15);\n");
3077 printf (" int i = n;\n");
3079 printf (" CDEF (i);\n");
3080 printf (" } while (i-- > 0);\n");
3086 printf (" int i = n;\n");
3088 printf (" CDEF (i);\n");
3089 printf (" } while (i++ < 14);\n");
3092 if (*r == '0') printf (" CDEF (0);\n");
3093 if (*r == 'n') printf (" CDEF (n);\n");
3094 if (*r == 'm') printf (" CDEF (m);\n");
3098 printf (" break;\n");
3107 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3108 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3109 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3110 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3111 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3112 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3113 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3114 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3115 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3116 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3117 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3118 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3119 printf (" switch (jump_table[iword]) {\n");
3121 gensim_caselist (tab);
3122 gensim_caselist (movsxy_tab);
3124 printf (" default:\n");
3126 printf (" RAISE_EXCEPTION (SIGILL);\n");
3137 for (p = tab; p->name; p++)
3140 printf ("#define OPC_");
3154 printf (" %d\n",p->index);
3158 static int ppi_index;
3160 /* Take a ppi code, expand all varying fields in it and fill all the
3161 right entries in 'table' with the opcode index.
3162 NOTE: tail recursion optimization removed for simplicity. */
3165 expand_ppi_code (val, i, s)
3175 fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]);
3180 if (warn_conflicts && table[val] != 0)
3181 conflict_warn (val, i);
3183 /* The last four bits are disregarded for the switch table. */
3187 /* Four-bit expansion. */
3188 for (j = 0; j < 16; j++)
3189 expand_ppi_code ((val << 4) + j, i, s + 4);
3193 expand_ppi_code ((val << 1), i, s + 1);
3196 expand_ppi_code ((val << 1) + 1, i, s + 1);
3201 expand_ppi_code ((val << 1), i, s + 1);
3202 expand_ppi_code ((val << 1) + 1, i, s + 1);
3205 expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2);
3206 expand_ppi_code ((val << 2) + 2, i, s + 2);
3207 expand_ppi_code ((val << 2) + 3, i, s + 2);
3218 for (p = ppi_tab; p->name; p++)
3220 p->index = ppi_index++;
3221 expand_ppi_code (0, p->index, p->code);
3230 printf ("#define DSR_MASK_G 0x80\n");
3231 printf ("#define DSR_MASK_Z 0x40\n");
3232 printf ("#define DSR_MASK_N 0x20\n");
3233 printf ("#define DSR_MASK_V 0x10\n");
3235 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3236 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3237 printf (" if (overflow && S) \\\n");
3239 printf (" if (res_grd & 0x80) \\\n");
3241 printf (" res = 0x80000000; \\\n");
3242 printf (" res_grd |= 0xff; \\\n");
3244 printf (" else \\\n");
3246 printf (" res = 0x7fffffff; \\\n");
3247 printf (" res_grd &= ~0xff; \\\n");
3249 printf (" overflow = 0; \\\n");
3251 printf ("} while (0)\n");
3253 printf ("#define ADD_SUB_GE \\\n");
3254 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3256 printf ("static void\n");
3257 printf ("ppi_insn (iword)\n");
3258 printf (" int iword;\n");
3260 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3261 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
3262 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3263 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
3264 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3265 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
3266 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3267 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
3268 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3269 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
3270 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3271 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
3273 printf (" int z;\n");
3274 printf (" int res, res_grd;\n");
3275 printf (" int carry, overflow, greater_equal;\n");
3277 printf (" switch (ppi_table[iword >> 4]) {\n");
3279 for (; p->name; p++)
3287 printf (" /* %s %s */\n", p->name, p->code);
3288 printf (" case %d: \n", p->index);
3291 for (shift = 16; *s; )
3296 printf (" int i = (iword >> 4) & 0x7f;\n");
3306 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3312 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3313 printf ("\treturn;\n");
3315 printf (" case %d: \n", p->index + 1);
3327 printf (" z = iword & 0xf;\n");
3335 else if (havedecl == 2)
3337 for (j = 0; j < MAX_NR_STUFF; j++)
3342 (havedecl == 2 ? " " : ""),
3350 printf (" if (iword & 0x200)\n");
3351 printf (" goto assign_z;\n");
3353 printf (" break;\n");
3357 printf (" default:\n");
3359 printf (" RAISE_EXCEPTION (SIGILL);\n");
3360 printf (" return;\n");
3363 printf (" DSR &= ~0xf1;\n");
3364 printf (" if (res || res_grd)\n");
3365 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3367 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3368 printf (" assign_dc:\n");
3369 printf (" switch (DSR >> 1 & 7)\n");
3371 printf (" case 0: /* Carry Mode */\n");
3372 printf (" DSR |= carry;\n");
3373 printf (" case 1: /* Negative Value Mode */\n");
3374 printf (" DSR |= res_grd >> 7 & 1;\n");
3375 printf (" case 2: /* Zero Value Mode */\n");
3376 printf (" DSR |= DSR >> 6 & 1;\n");
3377 printf (" case 3: /* Overflow mode\n");
3378 printf (" DSR |= overflow >> 4;\n");
3379 printf (" case 4: /* Signed Greater Than Mode */\n");
3380 printf (" DSR |= DSR >> 7 & 1;\n");
3381 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
3382 printf (" DSR |= greater_equal >> 7;\n");
3384 printf (" assign_z:\n");
3385 printf (" if (0xa05f >> z & 1)\n");
3387 printf (" RAISE_EXCEPTION (SIGILL);\n");
3388 printf (" return;\n");
3390 printf (" DSP_R (z) = res;\n");
3391 printf (" DSP_GRD (z) = res_grd;\n");
3400 /* Verify the table before anything else. */
3403 for (p = tab; p->name; p++)
3405 /* Check that the code field contains 16 bits. */
3406 if (strlen (p->code) != 16)
3408 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
3409 p->code, strlen (p->code), p->name);
3415 /* Now generate the requested data. */
3418 if (ac > 2 && strcmp (av[2], "-w") == 0)
3422 if (strcmp (av[1], "-t") == 0)
3426 else if (strcmp (av[1], "-d") == 0)
3430 else if (strcmp (av[1], "-s") == 0)
3433 dumptable ("sh_jump_table", 1 << 16, 0);
3435 memset (table, 0, sizeof table);
3436 filltable (movsxy_tab);
3437 expand_ppi_movxy ();
3438 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3440 memset (table, 0, sizeof table);
3442 dumptable ("ppi_table", 1 << 12, 0);
3444 else if (strcmp (av[1], "-x") == 0)
3447 filltable (movsxy_tab);
3450 else if (strcmp (av[1], "-p") == 0)
3457 fprintf (stderr, "Opcode table generation no longer supported.\n");