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",
438 " u.i &= 0x7fffffff;",
443 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
448 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
449 "FP_CMP (n, ==, m);",
452 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
457 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
458 "if (! FPSCR_PR || n & 1)",
459 " RAISE_EXCEPTION (SIGILL);",
473 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
474 "if (! FPSCR_PR || n & 1)",
475 " RAISE_EXCEPTION (SIGILL);",
489 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
491 "/* FIXME: check for DP and (n & 1) == 0? */",
495 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
497 " RAISE_EXCEPTION (SIGILL);",
501 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
502 " RAISE_EXCEPTION (SIGILL);",
503 " /* FIXME: check for nans and infinities. */",
504 " fsum += FR (v1+0) * FR (v2+0);",
505 " fsum += FR (v1+1) * FR (v2+1);",
506 " fsum += FR (v1+2) * FR (v2+2);",
507 " fsum += FR (v1+3) * FR (v2+3);",
508 " SET_FR (v1+3, fsum);",
513 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
514 "SET_FR (n, (float) 0.0);",
515 "/* FIXME: check for DP and (n & 1) == 0? */",
519 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
520 "SET_FR (n, (float) 1.0);",
521 "/* FIXME: check for DP and (n & 1) == 0? */",
525 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
536 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
539 " SET_DR (n, (double) FPUL);",
542 " SET_FR (n, (float) FPUL);",
547 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
548 "SET_FR (n, FR (m) * FR (0) + FR (n));",
549 "/* FIXME: check for DP and (n & 1) == 0? */",
553 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
556 " int ni = XD_TO_XF (n);",
557 " int mi = XD_TO_XF (m);",
558 " SET_XF (ni + 0, XF (mi + 0));",
559 " SET_XF (ni + 1, XF (mi + 1));",
563 " SET_FR (n, FR (m));",
567 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
576 " WLAT (R[n], FI (m));",
580 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
589 " SET_FI (n, RLAT (R[m]));",
593 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
594 "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
595 " and mov.bwl <REG_N>, @(disp12,<REG_M>)",
596 " and mov.bwl @(disp12,<REG_N>),<REG_M>",
597 " and movu.bw @(disp12,<REG_N>),<REG_M>. */",
598 "int word2 = RIAT (nip);",
599 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
600 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
602 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
605 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
615 " SET_FI (n, RLAT (R[m]));",
620 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
631 " WLAT (R[n], FI (m));",
635 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
639 " RDAT (R[0]+R[m], n);",
644 " SET_FI (n, RLAT (R[0] + R[m]));",
648 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
652 " WDAT (R[0]+R[n], m);",
657 " WLAT ((R[0]+R[n]), FI (m));",
662 See fmov instructions above for move to/from extended fp registers. */
665 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
670 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
677 " u.i ^= 0x80000000;",
682 { "", "", "fpchg", "1111011111111101",
683 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
687 { "", "", "frchg", "1111101111111101",
689 " RAISE_EXCEPTION (SIGILL);",
690 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
691 " RAISE_EXCEPTION (SIGILL);",
693 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
697 { "", "", "fsca", "1111eeee11111101",
699 " RAISE_EXCEPTION (SIGILL);",
700 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
701 " RAISE_EXCEPTION (SIGILL);",
704 " SET_FR (n, fsca_s (FPUL, &sin));",
705 " SET_FR (n+1, fsca_s (FPUL, &cos));",
710 { "", "", "fschg", "1111001111111101",
711 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
715 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
716 "FP_UNARY (n, sqrt);",
720 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
722 " RAISE_EXCEPTION (SIGILL);",
723 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
724 " RAISE_EXCEPTION (SIGILL);",
726 " SET_FR (n, fsrra_s (FR (n)));",
730 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
735 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
738 " if (DR (n) != DR (n)) /* NaN */",
739 " FPUL = 0x80000000;",
741 " FPUL = (int) DR (n);",
744 "if (FR (n) != FR (n)) /* NaN */",
745 " FPUL = 0x80000000;",
747 " FPUL = (int) FR (n);",
751 { "", "", "ftrv <FV_N>", "1111vv0111111101",
753 " RAISE_EXCEPTION (SIGILL);",
756 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
757 " RAISE_EXCEPTION (SIGILL);",
758 " /* FIXME not implemented. */",
759 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
764 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
774 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
775 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
776 "SET_NIP (PT2H (R[n]));",
778 "Delay_Slot (PC + 2);",
781 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
782 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
783 "PR = PH2T (PC + 4);",
785 " gotcall (PR, R[n]);",
786 "SET_NIP (PT2H (R[n]));",
788 "Delay_Slot (PC + 2);",
790 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
791 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
792 "PR = PH2T (PC + 2);",
794 " gotcall (PR, R[n]);",
795 "SET_NIP (PT2H (R[n]));",
797 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
798 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
799 "PR = PH2T (PC + 2);",
801 " gotcall (PR, i + TBR);",
802 "SET_NIP (PT2H (i + TBR));",
805 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
807 "/* FIXME: user mode */",
809 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
811 "/* FIXME: user mode */",
813 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
816 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
818 " DBR = R[n]; /* priv mode */",
820 " RAISE_EXCEPTION (SIGILL); /* user mode */",
822 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
824 " SGR = R[n]; /* priv mode */",
826 " RAISE_EXCEPTION (SIGILL); /* user mode */",
828 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
829 "if (SR_MD)", /* FIXME? */
830 " TBR = R[n]; /* priv mode */",
832 " RAISE_EXCEPTION (SIGILL); /* user mode */",
834 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
836 "CREG (m) = RLAT (R[n]);",
838 "/* FIXME: user mode */",
840 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
842 "SET_SR (RLAT (R[n]));",
844 "/* FIXME: user mode */",
846 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
848 "SET_MOD (RLAT (R[n]));",
851 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
855 " DBR = RLAT (R[n]);",
859 " RAISE_EXCEPTION (SIGILL); /* user mode */",
861 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
865 " SGR = RLAT (R[n]);",
869 " RAISE_EXCEPTION (SIGILL); /* user mode */",
873 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
874 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
876 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
877 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
881 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
883 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
884 "CHECK_INSN_PTR (insn_ptr);",
887 { "", "", "ldrc #<imm>", "10001010i8*1....",
889 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
890 "CHECK_INSN_PTR (insn_ptr);",
894 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
897 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
899 "SREG (m) = RLAT (R[n]);",
902 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
903 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
906 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
907 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
909 "SET_FPSCR (RLAT (R[n]));",
913 { "", "", "ldtlb", "0000000000111000",
914 "/* We don't implement cache or tlb, so this is a noop. */",
917 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
918 "macl (&R0, memory, n, m);",
921 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
922 "macw (&R0, memory, n, m, endianw);",
925 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
928 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
929 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
930 "R[n] = ((i << 24) >> 12) | RIAT (nip);",
931 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
933 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
934 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
935 "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
936 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
938 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
942 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
944 "R0 = RSBAT (i + GBR);",
947 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
949 "R0 = RSBAT (i + R[m]);",
952 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
954 "R[n] = RSBAT (R0 + R[m]);",
957 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
959 "R[n] = RSBAT (R[m]);",
963 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
966 "R0 = RSBAT (R[n]);",
969 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
971 "WBAT (R[n], R[m]);",
973 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
975 "WBAT (i + GBR, R0);",
977 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
979 "WBAT (i + R[m], R0);",
981 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
983 "WBAT (R[n] + R0, R[m]);",
985 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
986 /* Allow for the case where m == n. */
992 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
997 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
999 "R[n] = RSBAT (R[m]);",
1003 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
1005 "R0 = RLAT (i + GBR);",
1008 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
1009 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1011 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
1014 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1016 "R[n] = RLAT (i + R[m]);",
1019 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1021 "R[n] = RLAT (R0 + R[m]);",
1024 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1026 "R[n] = RLAT (R[m]);",
1030 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1033 "R0 = RLAT (R[n]);",
1036 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1038 "R[n] = RLAT (R[m]);",
1041 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1043 "WLAT (i + GBR, R0);",
1045 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1047 "WLAT (i + R[n], R[m]);",
1049 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1051 "WLAT (R0 + R[n], R[m]);",
1053 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1054 /* Allow for the case where m == n. */
1060 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1065 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1067 "WLAT (R[n], R[m]);",
1070 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1072 "R0 = RSWAT (i + GBR);",
1075 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1076 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1078 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1081 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1083 "R0 = RSWAT (i + R[m]);",
1086 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1088 "R[n] = RSWAT (R0 + R[m]);",
1091 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1093 "R[n] = RSWAT (R[m]);",
1097 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1100 "R0 = RSWAT (R[n]);",
1103 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1105 "R[n] = RSWAT (R[m]);",
1108 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1110 "WWAT (i + GBR, R0);",
1112 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1114 "WWAT (i + R[m], R0);",
1116 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1118 "WWAT (R0 + R[n], R[m]);",
1120 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1121 /* Allow for the case where m == n. */
1127 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1132 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1134 "WWAT (R[n], R[m]);",
1137 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1138 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1139 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1142 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1143 "/* We don't simulate cache, so this insn is identical to mov. */",
1145 "WLAT (R[n], R[0]);",
1148 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1151 "/* if (T) R0 -> (Rn) */",
1153 " WLAT (R[n], R[0]);",
1158 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1162 "R[0] = RLAT (R[n]);",
1163 "/* if (interrupt/exception) 0 -> LDST */",
1164 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1167 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1170 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1173 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1175 "int e = target_little_endian ? 3 : 0;",
1177 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1178 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1181 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1183 "int e = target_little_endian ? 3 : 0;",
1185 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1186 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1190 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1191 "MACL = ((int) R[n]) * ((int) R[m]);",
1193 #if 0 /* FIXME: The above cast to int is not really portable.
1194 It should be replaced by a SEXT32 macro. */
1195 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1196 "MACL = R[n] * R[m];",
1200 /* muls.w - see muls */
1201 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1202 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1205 /* mulu.w - see mulu */
1206 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1207 "MACL = (((unsigned int) (unsigned short) R[n])",
1208 " * ((unsigned int) (unsigned short) R[m]));",
1211 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1215 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1217 "SET_SR_T (ult > 0);",
1218 "R[n] = ult - R[m];",
1219 "SET_SR_T (T || (R[n] > ult));",
1222 { "", "", "nop", "0000000000001001",
1226 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1231 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1232 "/* Except for the effect on the cache - which is not simulated -",
1233 " this is like a nop. */",
1236 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1237 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1238 "/* FIXME: Cache not implemented */",
1241 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1242 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1243 "/* FIXME: Cache not implemented */",
1246 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1247 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1248 "/* FIXME: Cache not implemented */",
1251 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1254 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1257 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1259 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1262 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1263 "/* Except for the effect on the cache - which is not simulated -",
1264 " this is like a nop. */",
1268 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1269 "/* Except for the effect on the cache - which is not simulated -",
1270 " this is like a nop. */",
1274 { "", "", "synco", "0000000010101011",
1275 "/* Except for the effect on the pipeline - which is not simulated -",
1276 " this is like a nop. */",
1279 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1281 "R[n] = (R[n] << 1) | T;",
1285 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1287 "R[n] = (UR[n] >> 1) | (T << 31);",
1291 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1292 "SET_SR_T (R[n] < 0);",
1297 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1298 "SET_SR_T (R[n] & 1);",
1299 "R[n] = UR[n] >> 1;",
1300 "R[n] |= (T << 31);",
1303 { "", "", "rte", "0000000000101011",
1307 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1309 "SET_SR (RLAT (R[15]) & 0x3f3);",
1311 "Delay_Slot (PC + 2);",
1313 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1315 "SET_NIP (PT2H (SPC));",
1317 "Delay_Slot (PC + 2);",
1321 { "", "", "rts", "0000000000001011",
1322 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1323 "SET_NIP (PT2H (PR));",
1325 "Delay_Slot (PC + 2);",
1327 { "", "", "rts/n", "0000000001101011",
1328 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1329 "SET_NIP (PT2H (PR));",
1331 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1332 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1335 "SET_NIP (PT2H (PR));",
1339 { "", "", "setdmx", "0000000010011000",
1340 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1341 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1345 { "", "", "setdmy", "0000000011001000",
1346 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1347 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1351 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1354 { "", "", "setrc #<imm>", "10000010i8*1....",
1355 /* It would be more realistic to let loop_start point to some static
1356 memory that contains an illegal opcode and then give a bus error when
1357 the loop is eventually encountered, but it seems not only simpler,
1358 but also more debugging-friendly to just catch the failure here. */
1359 "if (BUSERROR (RS | RE, maskw))",
1360 " RAISE_EXCEPTION (SIGILL);",
1363 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1364 " CHECK_INSN_PTR (insn_ptr);",
1368 { "", "", "sets", "0000000001011000",
1372 { "", "", "sett", "0000000000011000",
1376 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1377 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1380 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1381 "SET_SR_T (R[n] < 0);",
1385 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1386 "SET_SR_T (R[n] & 1);",
1387 "R[n] = R[n] >> 1;",
1390 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1391 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1394 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1395 "SET_SR_T (R[n] < 0);",
1399 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1402 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1405 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1409 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1410 "SET_SR_T (R[n] & 1);",
1411 "R[n] = UR[n] >> 1;",
1414 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1415 "R[n] = UR[n] >> 2;",
1417 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1418 "R[n] = UR[n] >> 8;",
1420 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1421 "R[n] = UR[n] >> 16;",
1424 { "", "", "sleep", "0000000000011011",
1425 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1428 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1432 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1434 " R[n] = SGR; /* priv mode */",
1436 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1438 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1440 " R[n] = DBR; /* priv mode */",
1442 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1444 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1445 "if (SR_MD)", /* FIXME? */
1446 " R[n] = TBR; /* priv mode */",
1448 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1450 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1453 "WLAT (R[n], CREG (m));",
1455 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1457 "{ /* priv mode */",
1460 " WLAT (R[n], SGR);",
1463 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1465 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1467 "{ /* priv mode */",
1470 " WLAT (R[n], DBR);",
1473 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1476 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1479 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1482 "WLAT (R[n], SREG (m));",
1485 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1489 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1491 "SET_SR_T (ult > R[n]);",
1492 "R[n] = ult - R[m];",
1493 "SET_SR_T (T || (R[n] > ult));",
1496 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1497 "ult = R[n] - R[m];",
1498 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1502 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1503 "R[n] = ((R[m] & 0xffff0000)",
1504 " | ((R[m] << 8) & 0xff00)",
1505 " | ((R[m] >> 8) & 0x00ff));",
1507 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1508 "R[n] = (((R[m] << 16) & 0xffff0000)",
1509 " | ((R[m] >> 16) & 0x00ffff));",
1512 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1514 "ult = RBAT (R[n]);",
1515 "SET_SR_T (ult == 0);",
1516 "WBAT (R[n],ult|0x80);",
1519 { "0", "", "trapa #<imm>", "11000011i8*1....",
1520 "long imm = 0xff & i;",
1521 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1522 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1523 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1528 " WLAT (R[15], GET_SR ());",
1530 " WLAT (R[15], PH2T (PC + 2));",
1532 "else if (!SR_BL) {",
1533 " SSR = GET_SR ();",
1534 " SPC = PH2T (PC + 2);",
1535 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1536 " /* FIXME: EXPEVT = 0x00000160; */",
1538 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1542 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1543 "SET_SR_T ((R[n] & R[m]) == 0);",
1545 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1546 "SET_SR_T ((R0 & i) == 0);",
1548 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1550 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1553 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1556 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1559 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1561 "ult = RBAT (GBR+R0);",
1563 "WBAT (GBR + R0, ult);",
1566 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1567 "R[n] = (((R[n] >> 16) & 0xffff)",
1568 " | ((R[m] << 16) & 0xffff0000));",
1572 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1573 "divl (0, R[n], R[m]);",
1575 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1576 "divl (0, R[n], R[m]);",
1584 /* If this is disabled, the simulator speeds up by about 12% on a
1585 450 MHz PIII - 9% with ACE_FAST.
1586 Maybe we should have separate simulator loops? */
1588 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1591 "DSP_R (m) = RSWAT (R[n]) << 16;",
1592 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1594 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1596 "DSP_R (m) = RSWAT (R[n]) << 16;",
1597 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1599 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1601 "DSP_R (m) = RSWAT (R[n]) << 16;",
1602 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1605 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1607 "DSP_R (m) = RSWAT (R[n]) << 16;",
1608 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1611 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1614 "DSP_R (m) = RSWAT (R[n]);",
1616 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1618 "DSP_R (m) = RSWAT (R[n]);",
1620 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1622 "DSP_R (m) = RSWAT (R[n]);",
1625 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1627 "DSP_R (m) = RSWAT (R[n]);",
1630 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1633 "WWAT (R[n], DSP_R (m) >> 16);",
1635 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1637 "WWAT (R[n], DSP_R (m) >> 16);",
1639 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1641 "WWAT (R[n], DSP_R (m) >> 16);",
1644 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1646 "WWAT (R[n], DSP_R (m) >> 16);",
1649 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1652 "WWAT (R[n], SEXT (DSP_R (m)));",
1654 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1656 "WWAT (R[n], SEXT (DSP_R (m)));",
1658 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1660 "WWAT (R[n], SEXT (DSP_R (m)));",
1663 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1665 "WWAT (R[n], SEXT (DSP_R (m)));",
1668 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1671 "DSP_R (m) = RLAT (R[n]);",
1672 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1674 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1676 "DSP_R (m) = RLAT (R[n]);",
1677 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1679 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1681 "DSP_R (m) = RLAT (R[n]);",
1682 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1685 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1687 "DSP_R (m) = RLAT (R[n]);",
1688 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1691 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1694 "WLAT (R[n], DSP_R (m));",
1696 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1698 "WLAT (R[n], DSP_R (m));",
1700 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1702 "WLAT (R[n], DSP_R (m));",
1705 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1707 "WLAT (R[n], DSP_R (m));",
1710 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1713 "WLAT (R[n], SEXT (DSP_R (m)));",
1715 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1717 "WLAT (R[n], SEXT (DSP_R (m)));",
1719 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1721 "WLAT (R[n], SEXT (DSP_R (m)));",
1724 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1726 "WLAT (R[n], SEXT (DSP_R (m)));",
1729 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1730 "DSP_R (m) = RSWAT (R[n]) << 16;",
1733 " iword &= 0xfd53; goto top;",
1736 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1737 "DSP_R (m) = RLAT (R[n]);",
1739 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1740 "DSP_R (m) = RSWAT (R[n]) << 16;",
1741 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1744 " iword &= 0xfd53; goto top;",
1747 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1748 "DSP_R (m) = RLAT (R[n]);",
1749 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1751 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1752 "DSP_R (m) = RSWAT (R[n]) << 16;",
1753 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1756 " iword &= 0xfd53; goto top;",
1759 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1760 "DSP_R (m) = RLAT (R[n]);",
1761 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1763 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1764 "WWAT (R[n], DSP_R (m) >> 16);",
1767 " iword &= 0xfd53; goto top;",
1770 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1771 "WLAT (R[n], DSP_R (m));",
1773 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1774 "WWAT (R[n], DSP_R (m) >> 16);",
1775 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1778 " iword &= 0xfd53; goto top;",
1781 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1782 "WLAT (R[n], DSP_R (m));",
1783 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1785 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1786 "WWAT (R[n], DSP_R (m) >> 16);",
1787 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1790 " iword &= 0xfd53; goto top;",
1793 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1794 "WLAT (R[n], DSP_R (m));",
1795 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1797 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1798 "DSP_R (m) = RSWAT (R[n]) << 16;",
1800 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1801 "DSP_R (m) = RSWAT (R[n]) << 16;",
1802 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1804 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1805 "DSP_R (m) = RSWAT (R[n]) << 16;",
1806 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1808 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1809 "WWAT (R[n], DSP_R (m) >> 16);",
1811 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1812 "WWAT (R[n], DSP_R (m) >> 16);",
1813 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1815 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1816 "WWAT (R[n], DSP_R (m) >> 16);",
1817 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1819 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1820 "DSP_R (m) = RLAT (R[n]);",
1822 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1823 "DSP_R (m) = RLAT (R[n]);",
1824 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1826 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1827 "DSP_R (m) = RLAT (R[n]);",
1828 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1830 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1831 "WLAT (R[n], DSP_R (m));",
1833 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1834 "WLAT (R[n], DSP_R (m));",
1835 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1837 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1838 "WLAT (R[n], DSP_R (m));",
1839 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1841 { "", "", "nopx nopy", "1111000000000000",
1844 { "", "", "ppi", "1111100000000000",
1845 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1846 "ppi_insn (RIAT (nip));",
1847 "SET_NIP (nip + 2);",
1848 "iword &= 0xf7ff; goto top;",
1855 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1856 "int Sz = DSP_R (z) & 0xffff0000;",
1860 "else if (i >= 128 - 16)",
1861 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1864 " RAISE_EXCEPTION (SIGILL);",
1867 "res &= 0xffff0000;",
1871 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1872 "int Sz = DSP_R (z);",
1873 "int Sz_grd = GET_DSP_GRD (z);",
1885 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1887 " res_grd = SEXT (res_grd);",
1888 " carry = res_grd & 1;",
1890 "else if (i >= 96)",
1895 " res_grd = SIGN32 (Sz_grd);",
1900 " res = Sz >> i | Sz_grd << 32 - i;",
1901 " res_grd = Sz_grd >> i;",
1903 " carry = Sz >> (i - 1) & 1;",
1907 " RAISE_EXCEPTION (SIGILL);",
1910 "COMPUTE_OVERFLOW;",
1911 "greater_equal = 0;",
1913 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1914 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1915 "if (res == 0x80000000)",
1916 " res = 0x7fffffff;",
1918 "DSP_GRD (g) = SIGN32 (res);",
1921 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1922 "int Sx = DSP_R (x);",
1923 "int Sx_grd = GET_DSP_GRD (x);",
1924 "int Sy = DSP_R (y);",
1925 "int Sy_grd = SIGN32 (Sy);",
1927 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1928 "if (res == 0x80000000)",
1929 " res = 0x7fffffff;",
1931 "DSP_GRD (g) = SIGN32 (res);",
1935 "carry = (unsigned) res > (unsigned) Sx;",
1936 "res_grd = Sx_grd - Sy_grd - carry;",
1937 "COMPUTE_OVERFLOW;",
1940 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1941 "int Sx = DSP_R (x);",
1942 "int Sx_grd = GET_DSP_GRD (x);",
1943 "int Sy = DSP_R (y);",
1944 "int Sy_grd = SIGN32 (Sy);",
1946 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1947 "if (res == 0x80000000)",
1948 " res = 0x7fffffff;",
1950 "DSP_GRD (g) = SIGN32 (res);",
1954 "carry = (unsigned) res < (unsigned) Sx;",
1955 "res_grd = Sx_grd + Sy_grd + carry;",
1956 "COMPUTE_OVERFLOW;",
1958 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1959 "int Sx = DSP_R (x);",
1960 "int Sx_grd = GET_DSP_GRD (x);",
1961 "int Sy = DSP_R (y);",
1962 "int Sy_grd = SIGN32 (Sy);",
1964 "res = Sx - Sy - (DSR & 1);",
1965 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1966 "res_grd = Sx_grd + Sy_grd + carry;",
1967 "COMPUTE_OVERFLOW;",
1970 "if (res || res_grd)\n",
1971 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1973 " DSR |= DSR_MASK_Z | overflow;\n",
1977 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1978 "int Sx = DSP_R (x);",
1979 "int Sx_grd = GET_DSP_GRD (x);",
1980 "int Sy = DSP_R (y);",
1981 "int Sy_grd = SIGN32 (Sy);",
1983 "res = Sx + Sy + (DSR & 1);",
1984 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1985 "res_grd = Sx_grd + Sy_grd + carry;",
1986 "COMPUTE_OVERFLOW;",
1989 "if (res || res_grd)\n",
1990 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1992 " DSR |= DSR_MASK_Z | overflow;\n",
1996 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1997 "int Sx = DSP_R (x);",
1998 "int Sx_grd = GET_DSP_GRD (x);",
1999 "int Sy = DSP_R (y);",
2000 "int Sy_grd = SIGN32 (Sy);",
2002 "z = 17; /* Ignore result. */",
2004 "carry = (unsigned) res > (unsigned) Sx;",
2005 "res_grd = Sx_grd - Sy_grd - carry;",
2006 "COMPUTE_OVERFLOW;",
2009 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
2011 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
2013 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
2014 "/* FIXME: duplicate code pabs. */",
2016 "res_grd = GET_DSP_GRD (x);",
2022 " carry = (res != 0); /* The manual has a bug here. */",
2023 " res_grd = -res_grd - carry;",
2025 "COMPUTE_OVERFLOW;",
2026 "/* ??? The re-computing of overflow after",
2027 " saturation processing is specific to pabs. */",
2028 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2031 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2033 "res_grd = GET_DSP_GRD (x);",
2039 " carry = (res != 0); /* The manual has a bug here. */",
2040 " res_grd = -res_grd - carry;",
2042 "COMPUTE_OVERFLOW;",
2043 "/* ??? The re-computing of overflow after",
2044 " saturation processing is specific to pabs. */",
2045 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2049 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2050 "/* FIXME: duplicate code prnd. */",
2051 "int Sx = DSP_R (x);",
2052 "int Sx_grd = GET_DSP_GRD (x);",
2054 "res = (Sx + 0x8000) & 0xffff0000;",
2055 "carry = (unsigned) res < (unsigned) Sx;",
2056 "res_grd = Sx_grd + carry;",
2057 "COMPUTE_OVERFLOW;",
2060 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2061 "int Sx = DSP_R (x);",
2062 "int Sx_grd = GET_DSP_GRD (x);",
2064 "res = (Sx + 0x8000) & 0xffff0000;",
2065 "carry = (unsigned) res < (unsigned) Sx;",
2066 "res_grd = Sx_grd + carry;",
2067 "COMPUTE_OVERFLOW;",
2071 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2072 "/* FIXME: duplicate code pabs. */",
2076 "greater_equal = DSR_MASK_G;",
2086 " res = 0x7fffffff;",
2089 " overflow = DSR_MASK_V;",
2090 " greater_equal = 0;",
2095 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2099 "greater_equal = DSR_MASK_G;",
2109 " res = 0x7fffffff;",
2112 " overflow = DSR_MASK_V;",
2113 " greater_equal = 0;",
2118 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2119 "/* FIXME: duplicate code prnd. */",
2120 "int Sy = DSP_R (y);",
2121 "int Sy_grd = SIGN32 (Sy);",
2123 "res = (Sy + 0x8000) & 0xffff0000;",
2124 "carry = (unsigned) res < (unsigned) Sy;",
2125 "res_grd = Sy_grd + carry;",
2126 "COMPUTE_OVERFLOW;",
2129 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2130 "int Sy = DSP_R (y);",
2131 "int Sy_grd = SIGN32 (Sy);",
2133 "res = (Sy + 0x8000) & 0xffff0000;",
2134 "carry = (unsigned) res < (unsigned) Sy;",
2135 "res_grd = Sy_grd + carry;",
2136 "COMPUTE_OVERFLOW;",
2139 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2140 "int Sx = DSP_R (x) & 0xffff0000;",
2141 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2145 "else if (Sy >= 128 - 16)",
2146 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2149 " RAISE_EXCEPTION (SIGILL);",
2152 "goto cond_logical;",
2154 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2155 "int Sx = DSP_R (x);",
2156 "int Sx_grd = GET_DSP_GRD (x);",
2157 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2169 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2171 " res_grd = SEXT (res_grd);",
2172 " carry = res_grd & 1;",
2174 "else if (Sy >= 96)",
2179 " res_grd = SIGN32 (Sx_grd);",
2184 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
2185 " res_grd = Sx_grd >> Sy;",
2187 " carry = Sx >> (Sy - 1) & 1;",
2191 " RAISE_EXCEPTION (SIGILL);",
2194 "COMPUTE_OVERFLOW;",
2195 "greater_equal = 0;",
2197 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2198 "int Sx = DSP_R (x);",
2199 "int Sx_grd = GET_DSP_GRD (x);",
2200 "int Sy = DSP_R (y);",
2201 "int Sy_grd = SIGN32 (Sy);",
2204 "carry = (unsigned) res > (unsigned) Sx;",
2205 "res_grd = Sx_grd - Sy_grd - carry;",
2206 "COMPUTE_OVERFLOW;",
2209 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2210 "int Sx = DSP_R (x);",
2211 "int Sx_grd = GET_DSP_GRD (x);",
2212 "int Sy = DSP_R (y);",
2213 "int Sy_grd = SIGN32 (Sy);",
2216 "carry = (unsigned) res > (unsigned) Sy;",
2217 "res_grd = Sy_grd - Sx_grd - carry;",
2218 "COMPUTE_OVERFLOW;",
2221 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2222 "int Sx = DSP_R (x);",
2223 "int Sx_grd = GET_DSP_GRD (x);",
2224 "int Sy = DSP_R (y);",
2225 "int Sy_grd = SIGN32 (Sy);",
2228 "carry = (unsigned) res < (unsigned) Sx;",
2229 "res_grd = Sx_grd + Sy_grd + carry;",
2230 "COMPUTE_OVERFLOW;",
2233 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2234 "res = DSP_R (x) & DSP_R (y);",
2236 "res &= 0xffff0000;",
2238 "if (iword & 0x200)\n",
2239 " goto assign_z;\n",
2243 "greater_equal = 0;",
2246 " DSR |= res >> 26 & DSR_MASK_N;\n",
2248 " DSR |= DSR_MASK_Z;\n",
2249 "goto assign_dc;\n",
2251 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2252 "res = DSP_R (x) ^ DSP_R (y);",
2253 "goto cond_logical;",
2255 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2256 "res = DSP_R (x) | DSP_R (y);",
2257 "goto cond_logical;",
2259 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2260 "int Sx = DSP_R (x);",
2261 "int Sx_grd = GET_DSP_GRD (x);",
2263 "res = Sx - 0x10000;",
2264 "carry = res > Sx;",
2265 "res_grd = Sx_grd - carry;",
2266 "COMPUTE_OVERFLOW;",
2268 "res &= 0xffff0000;",
2270 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2271 "int Sx = DSP_R (x);",
2272 "int Sx_grd = GET_DSP_GRD (x);",
2274 "res = Sx + 0x10000;",
2275 "carry = res < Sx;",
2276 "res_grd = Sx_grd + carry;",
2277 "COMPUTE_OVERFLOW;",
2279 "res &= 0xffff0000;",
2281 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2282 "int Sy = DSP_R (y);",
2283 "int Sy_grd = SIGN32 (Sy);",
2285 "res = Sy - 0x10000;",
2286 "carry = res > Sy;",
2287 "res_grd = Sy_grd - carry;",
2288 "COMPUTE_OVERFLOW;",
2290 "res &= 0xffff0000;",
2292 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2293 "int Sy = DSP_R (y);",
2294 "int Sy_grd = SIGN32 (Sy);",
2296 "res = Sy + 0x10000;",
2297 "carry = res < Sy;",
2298 "res_grd = Sy_grd + carry;",
2299 "COMPUTE_OVERFLOW;",
2301 "res &= 0xffff0000;",
2303 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2308 "greater_equal = 1;",
2310 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2311 "/* Do multiply. */",
2312 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2313 "if (res == 0x80000000)",
2314 " res = 0x7fffffff;",
2316 "DSP_GRD (g) = SIGN32 (res);",
2317 "/* FIXME: update DSR based on results of multiply! */",
2325 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2326 "unsigned Sx = DSP_R (x);",
2327 "int Sx_grd = GET_DSP_GRD (x);",
2332 " Sx_grd = ~Sx_grd;",
2346 " if (Sx & ~0 << i)",
2354 "res_grd = SIGN32 (res);",
2359 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2360 "unsigned Sy = DSP_R (y);",
2369 " if (Sy & ~0 << i)",
2377 "res_grd = SIGN32 (res);",
2382 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2383 "int Sx = DSP_R (x);",
2384 "int Sx_grd = GET_DSP_GRD (x);",
2387 "carry = res != 0;",
2388 "res_grd = 0 - Sx_grd - carry;",
2389 "COMPUTE_OVERFLOW;",
2392 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2394 "res_grd = GET_DSP_GRD (x);",
2396 "COMPUTE_OVERFLOW;",
2399 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2400 "int Sy = DSP_R (y);",
2401 "int Sy_grd = SIGN32 (Sy);",
2404 "carry = res != 0;",
2405 "res_grd = 0 - Sy_grd - carry;",
2406 "COMPUTE_OVERFLOW;",
2409 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2411 "res_grd = SIGN32 (res);",
2413 "COMPUTE_OVERFLOW;",
2416 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2418 "res_grd = SIGN32 (res);",
2421 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2423 "res_grd = SIGN32 (res);",
2426 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2427 "if (0xa05f >> z & 1)",
2428 " RAISE_EXCEPTION (SIGILL);",
2430 " MACH = DSP_R (z);",
2433 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2434 "if (0xa05f >> z & 1)",
2435 " RAISE_EXCEPTION (SIGILL);",
2437 " MACL = DSP_R (z) = res;",
2441 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2442 "int Sx = DSP_R (x);",
2444 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2445 "res_grd = GET_DSP_GRD (x);",
2448 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2451 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2452 "int Sy = DSP_R (y);",
2454 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2455 "res_grd = SIGN32 (Sy);",
2458 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2464 /* Tables of things to put into enums for sh-opc.h */
2465 static char *nibble_type_list
[] =
2500 char *arg_type_list
[] =
2534 make_enum_list (name
, s
)
2539 printf ("typedef enum {\n");
2542 printf ("\t%s,\n", *s
);
2546 printf ("} %s;\n", name
);
2558 memcpy (bufa
, a
->code
, 4);
2559 memcpy (bufa
+ 4, a
->code
+ 12, 4);
2562 memcpy (bufb
, b
->code
, 4);
2563 memcpy (bufb
+ 4, b
->code
+ 12, 4);
2565 diff
= strcmp (bufa
, bufb
);
2566 /* Stabilize the sort, so that later entries can override more general
2567 preceding entries. */
2568 return diff
? diff
: a
- b
;
2582 qsort (tab
, len
, sizeof (*p
), qfunc
);
2590 for (p
= tab
; p
->name
; p
++)
2592 printf ("%s %-30s\n", p
->code
, p
->name
);
2596 static unsigned short table
[1 << 16];
2598 static int warn_conflicts
= 0;
2601 conflict_warn (val
, i
)
2608 fprintf (stderr
, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2609 val
, i
, table
[val
]);
2611 for (ix
= sizeof (tab
) / sizeof (tab
[0]); ix
>= 0; ix
--)
2612 if (tab
[ix
].index
== i
|| tab
[ix
].index
== j
)
2614 key
= ((tab
[ix
].code
[0] - '0') << 3) +
2615 ((tab
[ix
].code
[1] - '0') << 2) +
2616 ((tab
[ix
].code
[2] - '0') << 1) +
2617 ((tab
[ix
].code
[3] - '0'));
2619 if (val
>> 12 == key
)
2620 fprintf (stderr
, " %s -- %s\n", tab
[ix
].code
, tab
[ix
].name
);
2623 for (ix
= sizeof (movsxy_tab
) / sizeof (movsxy_tab
[0]); ix
>= 0; ix
--)
2624 if (movsxy_tab
[ix
].index
== i
|| movsxy_tab
[ix
].index
== j
)
2626 key
= ((movsxy_tab
[ix
].code
[0] - '0') << 3) +
2627 ((movsxy_tab
[ix
].code
[1] - '0') << 2) +
2628 ((movsxy_tab
[ix
].code
[2] - '0') << 1) +
2629 ((movsxy_tab
[ix
].code
[3] - '0'));
2631 if (val
>> 12 == key
)
2632 fprintf (stderr
, " %s -- %s\n",
2633 movsxy_tab
[ix
].code
, movsxy_tab
[ix
].name
);
2636 for (ix
= sizeof (ppi_tab
) / sizeof (ppi_tab
[0]); ix
>= 0; ix
--)
2637 if (ppi_tab
[ix
].index
== i
|| ppi_tab
[ix
].index
== j
)
2639 key
= ((ppi_tab
[ix
].code
[0] - '0') << 3) +
2640 ((ppi_tab
[ix
].code
[1] - '0') << 2) +
2641 ((ppi_tab
[ix
].code
[2] - '0') << 1) +
2642 ((ppi_tab
[ix
].code
[3] - '0'));
2644 if (val
>> 12 == key
)
2645 fprintf (stderr
, " %s -- %s\n",
2646 ppi_tab
[ix
].code
, ppi_tab
[ix
].name
);
2650 /* Take an opcode, expand all varying fields in it out and fill all the
2651 right entries in 'table' with the opcode index. */
2654 expand_opcode (val
, i
, s
)
2661 if (warn_conflicts
&& table
[val
] != 0)
2662 conflict_warn (val
, i
);
2672 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
2676 /* Consume an arbitrary number of ones and zeros. */
2678 j
= (j
<< 1) + (s
[m
++] - '0');
2679 } while (s
[m
] == '0' || s
[m
] == '1');
2680 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
2682 case 'N': /* NN -- four-way fork */
2683 for (j
= 0; j
< 4; j
++)
2684 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2686 case 'x': /* xx or xy -- two-way or four-way fork */
2687 for (j
= 0; j
< 4; j
+= (s
[1] == 'x' ? 2 : 1))
2688 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2690 case 'y': /* yy or yx -- two-way or four-way fork */
2691 for (j
= 0; j
< (s
[1] == 'x' ? 4 : 2); j
++)
2692 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2694 case '?': /* Seven-way "wildcard" fork for movxy */
2695 expand_opcode ((val
<< 2), i
, s
+ 2);
2696 for (j
= 1; j
< 4; j
++)
2698 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2699 expand_opcode ((val
<< 2) | (j
+ 16), i
, s
+ 2);
2702 case 'i': /* eg. "i8*1" */
2703 case '.': /* "...." is a wildcard */
2706 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2707 for (j
= 0; j
< 16; j
++)
2708 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2711 /* eeee -- even numbered register:
2713 for (j
= 0; j
< 15; j
+= 2)
2714 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2717 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2718 MMMM -- 10-way fork */
2719 expand_opcode ((val
<< 4) | 5, i
, s
+ 4);
2720 for (j
= 7; j
< 16; j
++)
2721 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2725 GGGG -- two-way fork */
2726 for (j
= 13; j
<= 15; j
+=2)
2727 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2730 /* ssss -- 10-way fork */
2731 /* System registers mach, macl, pr: */
2732 for (j
= 0; j
< 3; j
++)
2733 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2734 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2735 for (j
= 5; j
< 12; j
++)
2736 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2739 /* XX/XY -- 2/4 way fork. */
2740 for (j
= 0; j
< 4; j
+= (s
[1] == 'X' ? 2 : 1))
2741 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2744 /* aa/ax -- 2/4 way fork. */
2745 for (j
= 0; j
< 4; j
+= (s
[1] == 'a' ? 2 : 1))
2746 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2749 /* YY/YX -- 2/4 way fork. */
2750 for (j
= 0; j
< (s
[1] == 'Y' ? 2 : 4); j
+= 1)
2751 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2754 /* AA/AY: 2/4 way fork. */
2755 for (j
= 0; j
< (s
[1] == 'A' ? 2 : 4); j
+= 1)
2756 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2759 /* vv(VV) -- 4(16) way fork. */
2760 /* Vector register fv0/4/8/12. */
2763 /* 2 vector registers. */
2764 for (j
= 0; j
< 15; j
++)
2765 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2769 /* 1 vector register. */
2770 for (j
= 0; j
< 4; j
+= 1)
2771 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2778 /* Print the jump table used to index an opcode into a switch
2782 dumptable (name
, size
, start
)
2792 printf ("unsigned short %s[%d]={\n", name
, size
);
2793 while (i
< start
+ size
)
2797 printf ("/* 0x%x */\n", i
);
2804 printf ("%2d", table
[i
+ j
+ k
]);
2823 static int index
= 1;
2826 for (; p
->name
; p
++)
2829 expand_opcode (0, p
->index
, p
->code
);
2833 /* Table already contains all the switch case tags for 16-bit opcode double
2834 data transfer (ddt) insns, and the switch case tag for processing parallel
2835 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2836 latter tag to represent all combinations of ppi with ddt. */
2842 for (i
= 0xf000; i
< 0xf400; i
++)
2844 table
[i
+ 0x800] = table
[0xf800];
2851 for (; p
->name
; p
++)
2860 printf (" /* %s %s */\n", p
->name
, p
->code
);
2861 printf (" case %d: \n", p
->index
);
2869 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2874 /* Wildcard expansion, nothing to do here. */
2878 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2882 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2894 printf (" int n = (iword >> 8) & 0xf;\n");
2899 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2903 if (s
[1] == 'y') /* xy */
2905 printf (" int n = (iword & 3) ? \n");
2906 printf (" ((iword >> 9) & 1) + 4 : \n");
2907 printf (" REG_xy ((iword >> 8) & 3);\n");
2910 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2915 if (s
[1] == 'x') /* yx */
2917 printf (" int n = (iword & 0xc) ? \n");
2918 printf (" ((iword >> 8) & 1) + 6 : \n");
2919 printf (" REG_yx ((iword >> 8) & 3);\n");
2922 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2931 printf (" int m = (iword >> 4) & 0xf;\n");
2935 if (s
[1] == 'Y') /* XY */
2937 printf (" int m = (iword & 3) ? \n");
2938 printf (" ((iword >> 7) & 1) + 8 : \n");
2939 printf (" DSP_xy ((iword >> 6) & 3);\n");
2942 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2946 if (s
[1] == 'x') /* ax */
2948 printf (" int m = (iword & 3) ? \n");
2949 printf (" 7 - ((iword >> 6) & 2) : \n");
2950 printf (" DSP_ax ((iword >> 6) & 3);\n");
2953 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2957 if (s
[1] == 'X') /* YX */
2959 printf (" int m = (iword & 0xc) ? \n");
2960 printf (" ((iword >> 6) & 1) + 10 : \n");
2961 printf (" DSP_yx ((iword >> 6) & 3);\n");
2964 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2968 if (s
[1] == 'Y') /* AY */
2970 printf (" int m = (iword & 0xc) ? \n");
2971 printf (" 7 - ((iword >> 5) & 2) : \n");
2972 printf (" DSP_ay ((iword >> 6) & 3);\n");
2975 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2980 printf (" int i = (iword & 0x");
2986 "gensim_caselist: Unknown char '%c' in %s\n",
3007 "gensim_caselist: Unknown char '%c' in %s\n",
3011 case '.': /* eg. "i12." */
3028 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3029 sextbit
- 1, sextbit
- 1);
3033 printf (" TB (m,n);\n");
3035 printf (" TL (m);\n");
3037 printf (" TL (n);\n");
3042 for (r
= p
->refs
; *r
; r
++)
3044 if (*r
== 'f') printf (" CREF (15);\n");
3048 printf (" int i = n;\n");
3050 printf (" CREF (i);\n");
3051 printf (" } while (i-- > 0);\n");
3057 printf (" int i = n;\n");
3059 printf (" CREF (i);\n");
3060 printf (" } while (i++ < 14);\n");
3063 if (*r
== '0') printf (" CREF (0);\n");
3064 if (*r
== '8') printf (" CREF (8);\n");
3065 if (*r
== '9') printf (" CREF (9);\n");
3066 if (*r
== 'n') printf (" CREF (n);\n");
3067 if (*r
== 'm') printf (" CREF (m);\n");
3072 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3076 printf (" %s\n", p
->stuff
[j
]);
3084 for (r
= p
->defs
; *r
; r
++)
3086 if (*r
== 'f') printf (" CDEF (15);\n");
3090 printf (" int i = n;\n");
3092 printf (" CDEF (i);\n");
3093 printf (" } while (i-- > 0);\n");
3099 printf (" int i = n;\n");
3101 printf (" CDEF (i);\n");
3102 printf (" } while (i++ < 14);\n");
3105 if (*r
== '0') printf (" CDEF (0);\n");
3106 if (*r
== 'n') printf (" CDEF (n);\n");
3107 if (*r
== 'm') printf (" CDEF (m);\n");
3111 printf (" break;\n");
3120 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3121 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3122 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3123 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3124 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3125 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3126 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3127 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3128 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3129 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3130 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3131 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3132 printf (" switch (jump_table[iword]) {\n");
3134 gensim_caselist (tab
);
3135 gensim_caselist (movsxy_tab
);
3137 printf (" default:\n");
3139 printf (" RAISE_EXCEPTION (SIGILL);\n");
3150 for (p
= tab
; p
->name
; p
++)
3153 printf ("#define OPC_");
3167 printf (" %d\n",p
->index
);
3171 static int ppi_index
;
3173 /* Take a ppi code, expand all varying fields in it and fill all the
3174 right entries in 'table' with the opcode index.
3175 NOTE: tail recursion optimization removed for simplicity. */
3178 expand_ppi_code (val
, i
, s
)
3188 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n", s
[0]);
3193 if (warn_conflicts
&& table
[val
] != 0)
3194 conflict_warn (val
, i
);
3196 /* The last four bits are disregarded for the switch table. */
3200 /* Four-bit expansion. */
3201 for (j
= 0; j
< 16; j
++)
3202 expand_ppi_code ((val
<< 4) + j
, i
, s
+ 4);
3206 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3209 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3214 expand_ppi_code ((val
<< 1), i
, s
+ 1);
3215 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
3218 expand_ppi_code ((val
<< 2) + 1, ppi_index
++, s
+ 2);
3219 expand_ppi_code ((val
<< 2) + 2, i
, s
+ 2);
3220 expand_ppi_code ((val
<< 2) + 3, i
, s
+ 2);
3231 for (p
= ppi_tab
; p
->name
; p
++)
3233 p
->index
= ppi_index
++;
3234 expand_ppi_code (0, p
->index
, p
->code
);
3243 printf ("#define DSR_MASK_G 0x80\n");
3244 printf ("#define DSR_MASK_Z 0x40\n");
3245 printf ("#define DSR_MASK_N 0x20\n");
3246 printf ("#define DSR_MASK_V 0x10\n");
3248 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3249 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3250 printf (" if (overflow && S) \\\n");
3252 printf (" if (res_grd & 0x80) \\\n");
3254 printf (" res = 0x80000000; \\\n");
3255 printf (" res_grd |= 0xff; \\\n");
3257 printf (" else \\\n");
3259 printf (" res = 0x7fffffff; \\\n");
3260 printf (" res_grd &= ~0xff; \\\n");
3262 printf (" overflow = 0; \\\n");
3264 printf ("} while (0)\n");
3266 printf ("#define ADD_SUB_GE \\\n");
3267 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3269 printf ("static void\n");
3270 printf ("ppi_insn (iword)\n");
3271 printf (" int iword;\n");
3273 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3274 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
3275 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3276 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
3277 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3278 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
3279 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3280 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
3281 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3282 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
3283 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3284 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
3286 printf (" int z;\n");
3287 printf (" int res, res_grd;\n");
3288 printf (" int carry, overflow, greater_equal;\n");
3290 printf (" switch (ppi_table[iword >> 4]) {\n");
3292 for (; p
->name
; p
++)
3300 printf (" /* %s %s */\n", p
->name
, p
->code
);
3301 printf (" case %d: \n", p
->index
);
3304 for (shift
= 16; *s
; )
3309 printf (" int i = (iword >> 4) & 0x7f;\n");
3319 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3325 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3326 printf ("\treturn;\n");
3328 printf (" case %d: \n", p
->index
+ 1);
3340 printf (" z = iword & 0xf;\n");
3348 else if (havedecl
== 2)
3350 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
3355 (havedecl
== 2 ? " " : ""),
3363 printf (" if (iword & 0x200)\n");
3364 printf (" goto assign_z;\n");
3366 printf (" break;\n");
3370 printf (" default:\n");
3372 printf (" RAISE_EXCEPTION (SIGILL);\n");
3373 printf (" return;\n");
3376 printf (" DSR &= ~0xf1;\n");
3377 printf (" if (res || res_grd)\n");
3378 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3380 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3381 printf (" assign_dc:\n");
3382 printf (" switch (DSR >> 1 & 7)\n");
3384 printf (" case 0: /* Carry Mode */\n");
3385 printf (" DSR |= carry;\n");
3386 printf (" case 1: /* Negative Value Mode */\n");
3387 printf (" DSR |= res_grd >> 7 & 1;\n");
3388 printf (" case 2: /* Zero Value Mode */\n");
3389 printf (" DSR |= DSR >> 6 & 1;\n");
3390 printf (" case 3: /* Overflow mode\n");
3391 printf (" DSR |= overflow >> 4;\n");
3392 printf (" case 4: /* Signed Greater Than Mode */\n");
3393 printf (" DSR |= DSR >> 7 & 1;\n");
3394 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
3395 printf (" DSR |= greater_equal >> 7;\n");
3397 printf (" assign_z:\n");
3398 printf (" if (0xa05f >> z & 1)\n");
3400 printf (" RAISE_EXCEPTION (SIGILL);\n");
3401 printf (" return;\n");
3403 printf (" DSP_R (z) = res;\n");
3404 printf (" DSP_GRD (z) = res_grd;\n");
3413 /* Verify the table before anything else. */
3416 for (p
= tab
; p
->name
; p
++)
3418 /* Check that the code field contains 16 bits. */
3419 if (strlen (p
->code
) != 16)
3421 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
3422 p
->code
, strlen (p
->code
), p
->name
);
3428 /* Now generate the requested data. */
3431 if (ac
> 2 && strcmp (av
[2], "-w") == 0)
3435 if (strcmp (av
[1], "-t") == 0)
3439 else if (strcmp (av
[1], "-d") == 0)
3443 else if (strcmp (av
[1], "-s") == 0)
3446 dumptable ("sh_jump_table", 1 << 16, 0);
3448 memset (table
, 0, sizeof table
);
3449 filltable (movsxy_tab
);
3450 expand_ppi_movxy ();
3451 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3453 memset (table
, 0, sizeof table
);
3455 dumptable ("ppi_table", 1 << 12, 0);
3457 else if (strcmp (av
[1], "-x") == 0)
3460 filltable (movsxy_tab
);
3463 else if (strcmp (av
[1], "-p") == 0)
3470 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.216122 seconds and 5 git commands to generate.