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....",
88 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
93 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
97 " Delay_Slot (PC + 2);",
101 { "", "", "bra <bdisp12>", "1010i12.........",
102 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
104 "Delay_Slot (PC + 2);",
107 { "", "n", "braf <REG_N>", "0000nnnn00100011",
108 "SET_NIP (PC + 4 + R[n]);",
110 "Delay_Slot (PC + 2);",
113 { "", "", "bsr <bdisp12>", "1011i12.........",
114 "PR = PH2T (PC + 4);",
115 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
117 "Delay_Slot (PC + 2);",
120 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
121 "PR = PH2T (PC) + 4;",
122 "SET_NIP (PC + 4 + R[n]);",
124 "Delay_Slot (PC + 2);",
127 { "", "", "bt <bdisp8>", "10001001i8p1....",
129 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
134 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
136 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
138 " Delay_Slot (PC + 2);",
142 { "", "", "clrmac", "0000000000101000",
147 { "", "", "clrs", "0000000001001000",
151 { "", "", "clrt", "0000000000001000",
156 { "", "", "clrdmxy", "0000000010001000",
157 "saved_state.asregs.cregs.named.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
160 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
161 "SET_SR_T (R0 == SEXT (i));",
163 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
164 "SET_SR_T (R[n] == R[m]);",
166 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
167 "SET_SR_T (R[n] >= R[m]);",
169 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
170 "SET_SR_T (R[n] > R[m]);",
172 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
173 "SET_SR_T (UR[n] > UR[m]);",
175 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
176 "SET_SR_T (UR[n] >= UR[m]);",
178 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
179 "SET_SR_T (R[n] > 0);",
181 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
182 "SET_SR_T (R[n] >= 0);",
184 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
185 "ult = R[n] ^ R[m];",
186 "SET_SR_T (((ult & 0xff000000) == 0)",
187 " | ((ult & 0xff0000) == 0)",
188 " | ((ult & 0xff00) == 0)",
189 " | ((ult & 0xff) == 0));",
192 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
193 "SET_SR_Q ((R[n] & sbit) != 0);",
194 "SET_SR_M ((R[m] & sbit) != 0);",
195 "SET_SR_T (M != Q);",
198 { "", "", "div0u", "0000000000011001",
204 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
205 "div1 (&R0, m, n/*, T*/);",
208 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
209 "dmul (1/*signed*/, R[n], R[m]);",
212 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
213 "dmul (0/*unsigned*/, R[n], R[m]);",
216 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
218 "SET_SR_T (R[n] == 0);",
221 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
222 "R[n] = SEXT (R[m]);",
224 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
225 "R[n] = SEXTW (R[m]);",
228 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
229 "R[n] = (R[m] & 0xff);",
231 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
232 "R[n] = (R[m] & 0xffff);",
236 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
237 "FP_UNARY (n, fabs);",
238 "/* FIXME: FR (n) &= 0x7fffffff; */",
242 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
247 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
248 "FP_CMP (n, ==, m);",
251 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
256 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
257 "if (! FPSCR_PR || n & 1)",
258 " RAISE_EXCEPTION (SIGILL);",
272 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
273 "if (! FPSCR_PR || n & 1)",
274 " RAISE_EXCEPTION (SIGILL);",
288 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
290 "/* FIXME: check for DP and (n & 1) == 0? */",
294 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
296 " RAISE_EXCEPTION (SIGILL);",
300 " /* FIXME: check for nans and infinities. */",
301 " fsum += FR (v1+0) * FR (v2+0);",
302 " fsum += FR (v1+1) * FR (v2+1);",
303 " fsum += FR (v1+2) * FR (v2+2);",
304 " fsum += FR (v1+3) * FR (v2+3);",
305 " SET_FR (v1+3, fsum);",
310 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
311 "SET_FR (n, (float) 0.0);",
312 "/* FIXME: check for DP and (n & 1) == 0? */",
316 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
317 "SET_FR (n, (float) 1.0);",
318 "/* FIXME: check for DP and (n & 1) == 0? */",
322 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
333 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
336 " SET_DR (n, (double) FPUL);",
339 " SET_FR (n, (float) FPUL);",
344 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
345 "SET_FR (n, FR (m) * FR (0) + FR (n));",
346 "/* FIXME: check for DP and (n & 1) == 0? */",
350 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
353 " int ni = XD_TO_XF (n);",
354 " int mi = XD_TO_XF (m);",
355 " SET_XF (ni + 0, XF (mi + 0));",
356 " SET_XF (ni + 1, XF (mi + 1));",
360 " SET_FR (n, FR (m));",
364 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
373 " WLAT (R[n], FI (m));",
377 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
386 " SET_FI (n, RLAT (R[m]));",
390 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
400 " SET_FI (n, RLAT (R[m]));",
405 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
416 " WLAT (R[n], FI (m));",
420 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
424 " RDAT (R[0]+R[m], n);",
429 " SET_FI (n, RLAT (R[0] + R[m]));",
433 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
437 " WDAT (R[0]+R[n], m);",
442 " WLAT ((R[0]+R[n]), FI (m));",
447 See fmov instructions above for move to/from extended fp registers. */
450 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
455 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
460 { "", "", "fpchg", "1111011111111101",
461 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
465 { "", "", "frchg", "1111101111111101",
467 " RAISE_EXCEPTION (SIGILL);",
469 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
473 { "", "", "fsca", "1111eeee11111101",
475 " RAISE_EXCEPTION (SIGILL);",
478 " SET_FR (n, fsca_s (FPUL, &sin));",
479 " SET_FR (n+1, fsca_s (FPUL, &cos));",
484 { "", "", "fschg", "1111001111111101",
485 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
489 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
490 "FP_UNARY (n, sqrt);",
494 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
496 " RAISE_EXCEPTION (SIGILL);",
498 " SET_FR (n, fsrra_s (FR (n)));",
502 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
507 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
510 " if (DR (n) != DR (n)) /* NaN */",
511 " FPUL = 0x80000000;",
513 " FPUL = (int) DR (n);",
516 "if (FR (n) != FR (n)) /* NaN */",
517 " FPUL = 0x80000000;",
519 " FPUL = (int) FR (n);",
523 { "", "", "ftrv <FV_N>", "1111vv0111111101",
525 " RAISE_EXCEPTION (SIGILL);",
528 " /* FIXME not implemented. */",
529 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
534 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
544 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
545 "SET_NIP (PT2H (R[n]));",
547 "Delay_Slot (PC + 2);",
550 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
551 "PR = PH2T (PC + 4);",
553 " gotcall (PR, R[n]);",
554 "SET_NIP (PT2H (R[n]));",
556 "Delay_Slot (PC + 2);",
559 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
561 "/* FIXME: user mode */",
563 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
565 "/* FIXME: user mode */",
567 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
570 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
572 " DBR = R[n]; /* priv mode */",
574 " RAISE_EXCEPTION (SIGILL); /* user mode */",
576 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
578 " SGR = R[n]; /* priv mode */",
580 " RAISE_EXCEPTION (SIGILL); /* user mode */",
582 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
584 "CREG (m) = RLAT (R[n]);",
586 "/* FIXME: user mode */",
588 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
590 "SET_SR (RLAT (R[n]));",
592 "/* FIXME: user mode */",
594 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
596 "SET_MOD (RLAT (R[n]));",
599 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
603 " DBR = RLAT (R[n]);",
607 " RAISE_EXCEPTION (SIGILL); /* user mode */",
609 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
613 " SGR = RLAT (R[n]);",
617 " RAISE_EXCEPTION (SIGILL); /* user mode */",
621 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
622 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
624 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
625 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
629 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
631 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
632 "CHECK_INSN_PTR (insn_ptr);",
635 { "", "", "ldrc #<imm>", "10001010i8*1....",
637 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
638 "CHECK_INSN_PTR (insn_ptr);",
642 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
645 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
647 "SREG (m) = RLAT (R[n]);",
650 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
651 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
654 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
655 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
657 "SET_FPSCR (RLAT (R[n]));",
661 { "", "", "ldtlb", "0000000000111000",
662 "/* We don't implement cache or tlb, so this is a noop. */",
665 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
666 "macl (&R0, memory, n, m);",
669 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
670 "macw (&R0, memory, n, m, endianw);",
673 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
676 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
680 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
682 "R0 = RSBAT (i + GBR);",
685 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
687 "R0 = RSBAT (i + R[m]);",
690 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
692 "R[n] = RSBAT (R0 + R[m]);",
695 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
697 "R[n] = RSBAT (R[m]);",
701 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
703 "WBAT (R[n], R[m]);",
705 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
707 "WBAT (i + GBR, R0);",
709 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
711 "WBAT (i + R[m], R0);",
713 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
715 "WBAT (R[n] + R0, R[m]);",
717 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
720 "WBAT (R[n], R[m]);",
722 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
724 "R[n] = RSBAT (R[m]);",
728 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
730 "R0 = RLAT (i + GBR);",
733 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
735 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
738 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
740 "R[n] = RLAT (i + R[m]);",
743 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
745 "R[n] = RLAT (R0 + R[m]);",
748 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
750 "R[n] = RLAT (R[m]);",
754 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
756 "R[n] = RLAT (R[m]);",
759 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
761 "WLAT (i + GBR, R0);",
763 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
765 "WLAT (i + R[n], R[m]);",
767 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
769 "WLAT (R0 + R[n], R[m]);",
771 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
774 "WLAT (R[n], R[m]);",
776 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
778 "WLAT (R[n], R[m]);",
781 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
783 "R0 = RSWAT (i + GBR);",
786 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
788 "R[n] = RSWAT (PH2T (PC + 4 + i));",
791 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
793 "R0 = RSWAT (i + R[m]);",
796 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
798 "R[n] = RSWAT (R0 + R[m]);",
801 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
803 "R[n] = RSWAT (R[m]);",
807 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
809 "R[n] = RSWAT (R[m]);",
812 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
814 "WWAT (i + GBR, R0);",
816 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
818 "WWAT (i + R[m], R0);",
820 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
822 "WWAT (R0 + R[n], R[m]);",
824 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
827 "WWAT (R[n], R[m]);",
829 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
831 "WWAT (R[n], R[m]);",
834 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
835 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
838 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
839 "/* We don't simulate cache, so this insn is identical to mov. */",
841 "WLAT (R[n], R[0]);",
844 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
847 "/* if (T) R0 -> (Rn) */",
849 " WLAT (R[n], R[0]);",
854 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
858 "R[0] = RLAT (R[n]);",
859 "/* if (interrupt/exception) 0 -> LDST */",
860 "/* (we don't simulate asynchronous interrupts/exceptions) */",
863 { "n", "", "movt <REG_N>", "0000nnnn00101001",
867 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
870 "R[0] = (RBAT (regn) << 24) + (RBAT (regn + 1) << 16) + ",
871 " (RBAT (regn + 2) << 8) + RBAT (regn + 3);",
874 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
877 "R[0] = (RBAT (regn) << 24) + (RBAT (regn + 1) << 16) + ",
878 " (RBAT (regn + 2) << 8) + RBAT (regn + 3);",
882 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
883 "MACL = ((int) R[n]) * ((int) R[m]);",
885 #if 0 /* FIXME: The above cast to int is not really portable.
886 It should be replaced by a SEXT32 macro. */
887 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
888 "MACL = R[n] * R[m];",
892 /* muls.w - see muls */
893 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
894 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
897 /* mulu.w - see mulu */
898 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
899 "MACL = (((unsigned int) (unsigned short) R[n])",
900 " * ((unsigned int) (unsigned short) R[m]));",
903 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
907 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
909 "SET_SR_T (ult > 0);",
910 "R[n] = ult - R[m];",
911 "SET_SR_T (T || (R[n] > ult));",
914 { "", "", "nop", "0000000000001001",
918 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
923 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
924 "/* Except for the effect on the cache - which is not simulated -",
925 " this is like a nop. */",
928 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
929 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
930 "/* FIXME: Cache not implemented */",
933 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
934 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
935 "/* FIXME: Cache not implemented */",
938 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
939 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
940 "/* FIXME: Cache not implemented */",
943 { "0", "", "or #<imm>,R0", "11001011i8*1....",
946 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
949 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
951 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
954 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
955 "/* Except for the effect on the cache - which is not simulated -",
956 " this is like a nop. */",
960 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
961 "/* Except for the effect on the cache - which is not simulated -",
962 " this is like a nop. */",
966 { "", "", "synco", "0000000010101011",
967 "/* Except for the effect on the pipeline - which is not simulated -",
968 " this is like a nop. */",
971 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
973 "R[n] = (R[n] << 1) | T;",
977 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
979 "R[n] = (UR[n] >> 1) | (T << 31);",
983 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
984 "SET_SR_T (R[n] < 0);",
989 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
990 "SET_SR_T (R[n] & 1);",
991 "R[n] = UR[n] >> 1;",
992 "R[n] |= (T << 31);",
995 { "", "", "rte", "0000000000101011",
999 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1001 "SET_SR (RLAT (R[15]) & 0x3f3);",
1003 "Delay_Slot (PC + 2);",
1006 "SET_NIP (PT2H (SPC));",
1008 "Delay_Slot (PC + 2);",
1012 { "", "", "rts", "0000000000001011",
1013 "SET_NIP (PT2H (PR));",
1015 "Delay_Slot (PC + 2);",
1019 { "", "", "setdmx", "0000000010011000",
1020 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1021 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1025 { "", "", "setdmy", "0000000011001000",
1026 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1027 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1031 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1034 { "", "", "setrc #<imm>", "10000010i8*1....",
1035 /* It would be more realistic to let loop_start point to some static
1036 memory that contains an illegal opcode and then give a bus error when
1037 the loop is eventually encountered, but it seems not only simpler,
1038 but also more debugging-friendly to just catch the failure here. */
1039 "if (BUSERROR (RS | RE, maskw))",
1040 " RAISE_EXCEPTION (SIGILL);",
1043 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1044 " CHECK_INSN_PTR (insn_ptr);",
1048 { "", "", "sets", "0000000001011000",
1052 { "", "", "sett", "0000000000011000",
1056 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1057 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
1060 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1061 "SET_SR_T (R[n] < 0);",
1065 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1066 "SET_SR_T (R[n] & 1);",
1067 "R[n] = R[n] >> 1;",
1070 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1071 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
1074 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1075 "SET_SR_T (R[n] < 0);",
1079 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1082 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1085 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1089 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1090 "SET_SR_T (R[n] & 1);",
1091 "R[n] = UR[n] >> 1;",
1094 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1095 "R[n] = UR[n] >> 2;",
1097 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1098 "R[n] = UR[n] >> 8;",
1100 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1101 "R[n] = UR[n] >> 16;",
1104 { "", "", "sleep", "0000000000011011",
1105 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1108 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1112 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1114 " R[n] = SGR; /* priv mode */",
1116 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1118 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1120 " R[n] = DBR; /* priv mode */",
1122 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1124 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1127 "WLAT (R[n], CREG (m));",
1129 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1131 "{ /* priv mode */",
1134 " WLAT (R[n], SGR);",
1137 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1139 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1141 "{ /* priv mode */",
1144 " WLAT (R[n], DBR);",
1147 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1150 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1153 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1156 "WLAT (R[n], SREG (m));",
1159 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1163 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1165 "SET_SR_T (ult > R[n]);",
1166 "R[n] = ult - R[m];",
1167 "SET_SR_T (T || (R[n] > ult));",
1170 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1171 "ult = R[n] - R[m];",
1172 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1176 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1177 "R[n] = ((R[m] & 0xffff0000)",
1178 " | ((R[m] << 8) & 0xff00)",
1179 " | ((R[m] >> 8) & 0x00ff));",
1181 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1182 "R[n] = (((R[m] << 16) & 0xffff0000)",
1183 " | ((R[m] >> 16) & 0x00ffff));",
1186 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1188 "ult = RBAT (R[n]);",
1189 "SET_SR_T (ult == 0);",
1190 "WBAT (R[n],ult|0x80);",
1193 { "0", "", "trapa #<imm>", "11000011i8*1....",
1194 "long imm = 0xff & i;",
1195 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1196 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1201 " WLAT (R[15], GET_SR ());",
1203 " WLAT (R[15], PH2T (PC + 2));",
1205 "else if (!SR_BL) {",
1206 " SSR = GET_SR ();",
1207 " SPC = PH2T (PC + 2);",
1208 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1209 " /* FIXME: EXPEVT = 0x00000160; */",
1211 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1215 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1216 "SET_SR_T ((R[n] & R[m]) == 0);",
1218 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1219 "SET_SR_T ((R0 & i) == 0);",
1221 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1223 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1226 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1229 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1232 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1234 "ult = RBAT (GBR+R0);",
1236 "WBAT (GBR + R0, ult);",
1239 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1240 "R[n] = (((R[n] >> 16) & 0xffff)",
1241 " | ((R[m] << 16) & 0xffff0000));",
1245 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1246 "divl (0, R[n], R[m]);",
1248 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1249 "divl (0, R[n], R[m]);",
1257 /* If this is disabled, the simulator speeds up by about 12% on a
1258 450 MHz PIII - 9% with ACE_FAST.
1259 Maybe we should have separate simulator loops? */
1261 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1264 "DSP_R (m) = RSWAT (R[n]) << 16;",
1265 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1267 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1269 "DSP_R (m) = RSWAT (R[n]) << 16;",
1270 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1272 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1274 "DSP_R (m) = RSWAT (R[n]) << 16;",
1275 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1278 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1280 "DSP_R (m) = RSWAT (R[n]) << 16;",
1281 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1284 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1287 "DSP_R (m) = RSWAT (R[n]);",
1289 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1291 "DSP_R (m) = RSWAT (R[n]);",
1293 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1295 "DSP_R (m) = RSWAT (R[n]);",
1298 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1300 "DSP_R (m) = RSWAT (R[n]);",
1303 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1306 "WWAT (R[n], DSP_R (m) >> 16);",
1308 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1310 "WWAT (R[n], DSP_R (m) >> 16);",
1312 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1314 "WWAT (R[n], DSP_R (m) >> 16);",
1317 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1319 "WWAT (R[n], DSP_R (m) >> 16);",
1322 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1325 "WWAT (R[n], SEXT (DSP_R (m)));",
1327 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1329 "WWAT (R[n], SEXT (DSP_R (m)));",
1331 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1333 "WWAT (R[n], SEXT (DSP_R (m)));",
1336 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1338 "WWAT (R[n], SEXT (DSP_R (m)));",
1341 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1344 "DSP_R (m) = RLAT (R[n]);",
1345 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1347 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1349 "DSP_R (m) = RLAT (R[n]);",
1350 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1352 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1354 "DSP_R (m) = RLAT (R[n]);",
1355 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1358 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1360 "DSP_R (m) = RLAT (R[n]);",
1361 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1364 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1367 "WLAT (R[n], DSP_R (m));",
1369 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1371 "WLAT (R[n], DSP_R (m));",
1373 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1375 "WLAT (R[n], DSP_R (m));",
1378 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1380 "WLAT (R[n], DSP_R (m));",
1383 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1386 "WLAT (R[n], SEXT (DSP_R (m)));",
1388 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1390 "WLAT (R[n], SEXT (DSP_R (m)));",
1392 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1394 "WLAT (R[n], SEXT (DSP_R (m)));",
1397 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1399 "WLAT (R[n], SEXT (DSP_R (m)));",
1402 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1403 "DSP_R (m) = RSWAT (R[n]) << 16;",
1406 " iword &= 0xfd53; goto top;",
1409 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1410 "DSP_R (m) = RLAT (R[n]);",
1412 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1413 "DSP_R (m) = RSWAT (R[n]) << 16;",
1414 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1417 " iword &= 0xfd53; goto top;",
1420 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1421 "DSP_R (m) = RLAT (R[n]);",
1422 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1424 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1425 "DSP_R (m) = RSWAT (R[n]) << 16;",
1426 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1429 " iword &= 0xfd53; goto top;",
1432 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1433 "DSP_R (m) = RLAT (R[n]);",
1434 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1436 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1437 "WWAT (R[n], DSP_R (m) >> 16);",
1440 " iword &= 0xfd53; goto top;",
1443 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1444 "WLAT (R[n], DSP_R (m));",
1446 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1447 "WWAT (R[n], DSP_R (m) >> 16);",
1448 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1451 " iword &= 0xfd53; goto top;",
1454 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1455 "WLAT (R[n], DSP_R (m));",
1456 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1458 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1459 "WWAT (R[n], DSP_R (m) >> 16);",
1460 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1463 " iword &= 0xfd53; goto top;",
1466 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1467 "WLAT (R[n], DSP_R (m));",
1468 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1470 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1471 "DSP_R (m) = RSWAT (R[n]) << 16;",
1473 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1474 "DSP_R (m) = RSWAT (R[n]) << 16;",
1475 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1477 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1478 "DSP_R (m) = RSWAT (R[n]) << 16;",
1479 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1481 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1482 "WWAT (R[n], DSP_R (m) >> 16);",
1484 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1485 "WWAT (R[n], DSP_R (m) >> 16);",
1486 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1488 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1489 "WWAT (R[n], DSP_R (m) >> 16);",
1490 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1492 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1493 "DSP_R (m) = RLAT (R[n]);",
1495 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1496 "DSP_R (m) = RLAT (R[n]);",
1497 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1499 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1500 "DSP_R (m) = RLAT (R[n]);",
1501 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1503 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1504 "WLAT (R[n], DSP_R (m));",
1506 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1507 "WLAT (R[n], DSP_R (m));",
1508 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1510 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1511 "WLAT (R[n], DSP_R (m));",
1512 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1514 { "", "", "nopx nopy", "1111000000000000",
1517 { "", "", "ppi", "1111100000000000",
1518 "ppi_insn (RIAT (nip));",
1520 "iword &= 0xf7ff; goto top;",
1527 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1528 "int Sz = DSP_R (z) & 0xffff0000;",
1532 "else if (i >= 128 - 16)",
1533 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1536 " RAISE_EXCEPTION (SIGILL);",
1539 "res &= 0xffff0000;",
1543 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1544 "int Sz = DSP_R (z);",
1545 "int Sz_grd = GET_DSP_GRD (z);",
1557 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1559 " res_grd = SEXT (res_grd);",
1560 " carry = res_grd & 1;",
1562 "else if (i >= 96)",
1567 " res_grd = SIGN32 (Sz_grd);",
1572 " res = Sz >> i | Sz_grd << 32 - i;",
1573 " res_grd = Sz_grd >> i;",
1575 " carry = Sz >> (i - 1) & 1;",
1579 " RAISE_EXCEPTION (SIGILL);",
1582 "COMPUTE_OVERFLOW;",
1583 "greater_equal = 0;",
1585 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1586 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1587 "if (res == 0x80000000)",
1588 " res = 0x7fffffff;",
1590 "DSP_GRD (g) = SIGN32 (res);",
1593 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1594 "int Sx = DSP_R (x);",
1595 "int Sx_grd = GET_DSP_GRD (x);",
1596 "int Sy = DSP_R (y);",
1597 "int Sy_grd = SIGN32 (Sy);",
1599 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1600 "if (res == 0x80000000)",
1601 " res = 0x7fffffff;",
1603 "DSP_GRD (g) = SIGN32 (res);",
1607 "carry = (unsigned) res > (unsigned) Sx;",
1608 "res_grd = Sx_grd - Sy_grd - carry;",
1609 "COMPUTE_OVERFLOW;",
1612 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1613 "int Sx = DSP_R (x);",
1614 "int Sx_grd = GET_DSP_GRD (x);",
1615 "int Sy = DSP_R (y);",
1616 "int Sy_grd = SIGN32 (Sy);",
1618 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1619 "if (res == 0x80000000)",
1620 " res = 0x7fffffff;",
1622 "DSP_GRD (g) = SIGN32 (res);",
1626 "carry = (unsigned) res < (unsigned) Sx;",
1627 "res_grd = Sx_grd + Sy_grd + carry;",
1628 "COMPUTE_OVERFLOW;",
1630 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1631 "int Sx = DSP_R (x);",
1632 "int Sx_grd = GET_DSP_GRD (x);",
1633 "int Sy = DSP_R (y);",
1634 "int Sy_grd = SIGN32 (Sy);",
1636 "res = Sx - Sy - (DSR & 1);",
1637 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1638 "res_grd = Sx_grd + Sy_grd + carry;",
1639 "COMPUTE_OVERFLOW;",
1642 "if (res || res_grd)\n",
1643 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1645 " DSR |= DSR_MASK_Z | overflow;\n",
1649 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1650 "int Sx = DSP_R (x);",
1651 "int Sx_grd = GET_DSP_GRD (x);",
1652 "int Sy = DSP_R (y);",
1653 "int Sy_grd = SIGN32 (Sy);",
1655 "res = Sx + Sy + (DSR & 1);",
1656 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1657 "res_grd = Sx_grd + Sy_grd + carry;",
1658 "COMPUTE_OVERFLOW;",
1661 "if (res || res_grd)\n",
1662 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1664 " DSR |= DSR_MASK_Z | overflow;\n",
1668 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1669 "int Sx = DSP_R (x);",
1670 "int Sx_grd = GET_DSP_GRD (x);",
1671 "int Sy = DSP_R (y);",
1672 "int Sy_grd = SIGN32 (Sy);",
1674 "z = 17; /* Ignore result. */",
1676 "carry = (unsigned) res > (unsigned) Sx;",
1677 "res_grd = Sx_grd - Sy_grd - carry;",
1678 "COMPUTE_OVERFLOW;",
1681 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1683 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1685 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
1686 "/* FIXME: duplicate code pabs. */",
1688 "res_grd = GET_DSP_GRD (x);",
1694 " carry = (res != 0); /* The manual has a bug here. */",
1695 " res_grd = -res_grd - carry;",
1697 "COMPUTE_OVERFLOW;",
1698 "/* ??? The re-computing of overflow after",
1699 " saturation processing is specific to pabs. */",
1700 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1703 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1705 "res_grd = GET_DSP_GRD (x);",
1711 " carry = (res != 0); /* The manual has a bug here. */",
1712 " res_grd = -res_grd - carry;",
1714 "COMPUTE_OVERFLOW;",
1715 "/* ??? The re-computing of overflow after",
1716 " saturation processing is specific to pabs. */",
1717 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1721 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
1722 "/* FIXME: duplicate code prnd. */",
1723 "int Sx = DSP_R (x);",
1724 "int Sx_grd = GET_DSP_GRD (x);",
1726 "res = (Sx + 0x8000) & 0xffff0000;",
1727 "carry = (unsigned) res < (unsigned) Sx;",
1728 "res_grd = Sx_grd + carry;",
1729 "COMPUTE_OVERFLOW;",
1732 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1733 "int Sx = DSP_R (x);",
1734 "int Sx_grd = GET_DSP_GRD (x);",
1736 "res = (Sx + 0x8000) & 0xffff0000;",
1737 "carry = (unsigned) res < (unsigned) Sx;",
1738 "res_grd = Sx_grd + carry;",
1739 "COMPUTE_OVERFLOW;",
1743 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
1744 "/* FIXME: duplicate code pabs. */",
1748 "greater_equal = DSR_MASK_G;",
1758 " res = 0x7fffffff;",
1761 " overflow = DSR_MASK_V;",
1762 " greater_equal = 0;",
1767 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1771 "greater_equal = DSR_MASK_G;",
1781 " res = 0x7fffffff;",
1784 " overflow = DSR_MASK_V;",
1785 " greater_equal = 0;",
1790 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
1791 "/* FIXME: duplicate code prnd. */",
1792 "int Sy = DSP_R (y);",
1793 "int Sy_grd = SIGN32 (Sy);",
1795 "res = (Sy + 0x8000) & 0xffff0000;",
1796 "carry = (unsigned) res < (unsigned) Sy;",
1797 "res_grd = Sy_grd + carry;",
1798 "COMPUTE_OVERFLOW;",
1801 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1802 "int Sy = DSP_R (y);",
1803 "int Sy_grd = SIGN32 (Sy);",
1805 "res = (Sy + 0x8000) & 0xffff0000;",
1806 "carry = (unsigned) res < (unsigned) Sy;",
1807 "res_grd = Sy_grd + carry;",
1808 "COMPUTE_OVERFLOW;",
1811 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1812 "int Sx = DSP_R (x) & 0xffff0000;",
1813 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1817 "else if (Sy >= 128 - 16)",
1818 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
1821 " RAISE_EXCEPTION (SIGILL);",
1824 "goto cond_logical;",
1826 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1827 "int Sx = DSP_R (x);",
1828 "int Sx_grd = GET_DSP_GRD (x);",
1829 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1841 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1843 " res_grd = SEXT (res_grd);",
1844 " carry = res_grd & 1;",
1846 "else if (Sy >= 96)",
1851 " res_grd = SIGN32 (Sx_grd);",
1856 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1857 " res_grd = Sx_grd >> Sy;",
1859 " carry = Sx >> (Sy - 1) & 1;",
1863 " RAISE_EXCEPTION (SIGILL);",
1866 "COMPUTE_OVERFLOW;",
1867 "greater_equal = 0;",
1869 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1870 "int Sx = DSP_R (x);",
1871 "int Sx_grd = GET_DSP_GRD (x);",
1872 "int Sy = DSP_R (y);",
1873 "int Sy_grd = SIGN32 (Sy);",
1876 "carry = (unsigned) res > (unsigned) Sx;",
1877 "res_grd = Sx_grd - Sy_grd - carry;",
1878 "COMPUTE_OVERFLOW;",
1881 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
1882 "int Sx = DSP_R (x);",
1883 "int Sx_grd = GET_DSP_GRD (x);",
1884 "int Sy = DSP_R (y);",
1885 "int Sy_grd = SIGN32 (Sy);",
1888 "carry = (unsigned) res > (unsigned) Sy;",
1889 "res_grd = Sy_grd - Sx_grd - carry;",
1890 "COMPUTE_OVERFLOW;",
1893 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1894 "int Sx = DSP_R (x);",
1895 "int Sx_grd = GET_DSP_GRD (x);",
1896 "int Sy = DSP_R (y);",
1897 "int Sy_grd = SIGN32 (Sy);",
1900 "carry = (unsigned) res < (unsigned) Sx;",
1901 "res_grd = Sx_grd + Sy_grd + carry;",
1902 "COMPUTE_OVERFLOW;",
1905 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1906 "res = DSP_R (x) & DSP_R (y);",
1908 "res &= 0xffff0000;",
1910 "if (iword & 0x200)\n",
1911 " goto assign_z;\n",
1915 "greater_equal = 0;",
1918 " DSR |= res >> 26 & DSR_MASK_N;\n",
1920 " DSR |= DSR_MASK_Z;\n",
1921 "goto assign_dc;\n",
1923 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1924 "res = DSP_R (x) ^ DSP_R (y);",
1925 "goto cond_logical;",
1927 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1928 "res = DSP_R (x) | DSP_R (y);",
1929 "goto cond_logical;",
1931 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1932 "int Sx = DSP_R (x);",
1933 "int Sx_grd = GET_DSP_GRD (x);",
1935 "res = Sx - 0x10000;",
1936 "carry = res > Sx;",
1937 "res_grd = Sx_grd - carry;",
1938 "COMPUTE_OVERFLOW;",
1940 "res &= 0xffff0000;",
1942 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1943 "int Sx = DSP_R (x);",
1944 "int Sx_grd = GET_DSP_GRD (x);",
1946 "res = Sx + 0x10000;",
1947 "carry = res < Sx;",
1948 "res_grd = Sx_grd + carry;",
1949 "COMPUTE_OVERFLOW;",
1951 "res &= 0xffff0000;",
1953 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1954 "int Sy = DSP_R (y);",
1955 "int Sy_grd = SIGN32 (Sy);",
1957 "res = Sy - 0x10000;",
1958 "carry = res > Sy;",
1959 "res_grd = Sy_grd - carry;",
1960 "COMPUTE_OVERFLOW;",
1962 "res &= 0xffff0000;",
1964 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1965 "int Sy = DSP_R (y);",
1966 "int Sy_grd = SIGN32 (Sy);",
1968 "res = Sy + 0x10000;",
1969 "carry = res < Sy;",
1970 "res_grd = Sy_grd + carry;",
1971 "COMPUTE_OVERFLOW;",
1973 "res &= 0xffff0000;",
1975 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1980 "greater_equal = 1;",
1982 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
1983 "/* Do multiply. */",
1984 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1985 "if (res == 0x80000000)",
1986 " res = 0x7fffffff;",
1988 "DSP_GRD (g) = SIGN32 (res);",
1989 "/* FIXME: update DSR based on results of multiply! */",
1997 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1998 "unsigned Sx = DSP_R (x);",
1999 "int Sx_grd = GET_DSP_GRD (x);",
2004 " Sx_grd = ~Sx_grd;",
2018 " if (Sx & ~0 << i)",
2026 "res_grd = SIGN32 (res);",
2031 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2032 "unsigned Sy = DSP_R (y);",
2041 " if (Sy & ~0 << i)",
2049 "res_grd = SIGN32 (res);",
2054 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2055 "int Sx = DSP_R (x);",
2056 "int Sx_grd = GET_DSP_GRD (x);",
2059 "carry = res != 0;",
2060 "res_grd = 0 - Sx_grd - carry;",
2061 "COMPUTE_OVERFLOW;",
2064 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2066 "res_grd = GET_DSP_GRD (x);",
2068 "COMPUTE_OVERFLOW;",
2071 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2072 "int Sy = DSP_R (y);",
2073 "int Sy_grd = SIGN32 (Sy);",
2076 "carry = res != 0;",
2077 "res_grd = 0 - Sy_grd - carry;",
2078 "COMPUTE_OVERFLOW;",
2081 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2083 "res_grd = SIGN32 (res);",
2085 "COMPUTE_OVERFLOW;",
2088 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2090 "res_grd = SIGN32 (res);",
2093 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2095 "res_grd = SIGN32 (res);",
2098 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2099 "if (0xa05f >> z & 1)",
2100 " RAISE_EXCEPTION (SIGILL);",
2102 " MACH = DSP_R (z);",
2105 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2106 "if (0xa05f >> z & 1)",
2107 " RAISE_EXCEPTION (SIGILL);",
2109 " MACL = DSP_R (z) = res;",
2113 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2114 "int Sx = DSP_R (x);",
2116 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2117 "res_grd = GET_DSP_GRD (x);",
2120 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2123 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2124 "int Sy = DSP_R (y);",
2126 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2127 "res_grd = SIGN32 (Sy);",
2130 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2136 /* Tables of things to put into enums for sh-opc.h */
2137 static char *nibble_type_list
[] =
2172 char *arg_type_list
[] =
2206 make_enum_list (name
, s
)
2211 printf ("typedef enum {\n");
2214 printf ("\t%s,\n", *s
);
2218 printf ("} %s;\n", name
);
2230 memcpy (bufa
, a
->code
, 4);
2231 memcpy (bufa
+ 4, a
->code
+ 12, 4);
2234 memcpy (bufb
, b
->code
, 4);
2235 memcpy (bufb
+ 4, b
->code
+ 12, 4);
2237 diff
= strcmp (bufa
, bufb
);
2238 /* Stabilize the sort, so that later entries can override more general
2239 preceding entries. */
2240 return diff
? diff
: a
- b
;
2254 qsort (tab
, len
, sizeof (*p
), qfunc
);
2262 for (p
= tab
; p
->name
; p
++)
2264 printf ("%s %-30s\n", p
->code
, p
->name
);
2268 static unsigned short table
[1 << 16];
2270 /* Take an opcode, expand all varying fields in it out and fill all the
2271 right entries in 'table' with the opcode index. */
2274 expand_opcode (val
, i
, s
)
2290 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
2294 /* Consume an arbitrary number of ones and zeros. */
2296 j
= (j
<< 1) + (s
[m
++] - '0');
2297 } while (s
[m
] == '0' || s
[m
] == '1');
2298 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
2300 case 'N': /* NN -- four-way fork */
2301 for (j
= 0; j
< 4; j
++)
2302 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2304 case 'x': /* xx or xy -- two-way or four-way fork */
2305 for (j
= 0; j
< 4; j
+= (s
[1] == 'x' ? 2 : 1))
2306 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2308 case 'y': /* yy or yx -- two-way or four-way fork */
2309 for (j
= 0; j
< (s
[1] == 'x' ? 4 : 2); j
++)
2310 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2312 case '?': /* Seven-way "wildcard" fork for movxy */
2313 expand_opcode ((val
<< 2), i
, s
+ 2);
2314 for (j
= 1; j
< 4; j
++)
2316 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2317 expand_opcode ((val
<< 2) | (j
+ 16), i
, s
+ 2);
2320 case 'i': /* eg. "i8*1" */
2321 case '.': /* "...." is a wildcard */
2324 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2325 for (j
= 0; j
< 16; j
++)
2326 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2329 /* eeee -- even numbered register:
2331 for (j
= 0; j
< 15; j
+= 2)
2332 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2335 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2336 MMMM -- 10-way fork */
2337 expand_opcode ((val
<< 4) | 5, i
, s
+ 4);
2338 for (j
= 7; j
< 16; j
++)
2339 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2343 GGGG -- two-way fork */
2344 for (j
= 13; j
<= 15; j
+=2)
2345 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2348 /* ssss -- 10-way fork */
2349 /* System registers mach, macl, pr: */
2350 for (j
= 0; j
< 3; j
++)
2351 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2352 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2353 for (j
= 5; j
< 12; j
++)
2354 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2357 /* XX/XY -- 2/4 way fork. */
2358 for (j
= 0; j
< 4; j
+= (s
[1] == 'X' ? 2 : 1))
2359 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2362 /* aa/ax -- 2/4 way fork. */
2363 for (j
= 0; j
< 4; j
+= (s
[1] == 'a' ? 2 : 1))
2364 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2367 /* YY/YX -- 2/4 way fork. */
2368 for (j
= 0; j
< (s
[1] == 'Y' ? 2 : 4); j
+= 1)
2369 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2372 /* AA/AY: 2/4 way fork. */
2373 for (j
= 0; j
< (s
[1] == 'A' ? 2 : 4); j
+= 1)
2374 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2377 /* vv(VV) -- 4(16) way fork. */
2378 /* Vector register fv0/4/8/12. */
2381 /* 2 vector registers. */
2382 for (j
= 0; j
< 15; j
++)
2383 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2387 /* 1 vector register. */
2388 for (j
= 0; j
< 4; j
+= 1)
2389 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2396 /* Print the jump table used to index an opcode into a switch
2400 dumptable (name
, size
, start
)
2410 printf ("unsigned short %s[%d]={\n", name
, size
);
2411 while (i
< start
+ size
)
2415 printf ("/* 0x%x */\n", i
);
2422 printf ("%2d", table
[i
+ j
+ k
]);
2441 static int index
= 1;
2444 for (; p
->name
; p
++)
2447 expand_opcode (0, p
->index
, p
->code
);
2451 /* Table already contains all the switch case tags for 16-bit opcode double
2452 data transfer (ddt) insns, and the switch case tag for processing parallel
2453 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2454 latter tag to represent all combinations of ppi with ddt. */
2460 for (i
= 0xf000; i
< 0xf400; i
++)
2462 table
[i
+ 0x800] = table
[0xf800];
2469 for (; p
->name
; p
++)
2478 printf (" /* %s %s */\n", p
->name
, p
->code
);
2479 printf (" case %d: \n", p
->index
);
2487 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2492 /* Wildcard expansion, nothing to do here. */
2496 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2500 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2512 printf (" int n = (iword >> 8) & 0xf;\n");
2517 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2521 if (s
[1] == 'y') /* xy */
2523 printf (" int n = (iword & 3) ? \n");
2524 printf (" ((iword >> 9) & 1) + 4 : \n");
2525 printf (" REG_xy ((iword >> 8) & 3);\n");
2528 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2533 if (s
[1] == 'x') /* yx */
2535 printf (" int n = (iword & 0xc) ? \n");
2536 printf (" ((iword >> 8) & 1) + 6 : \n");
2537 printf (" REG_yx ((iword >> 8) & 3);\n");
2540 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2549 printf (" int m = (iword >> 4) & 0xf;\n");
2553 if (s
[1] == 'Y') /* XY */
2555 printf (" int m = (iword & 3) ? \n");
2556 printf (" ((iword >> 7) & 1) + 8 : \n");
2557 printf (" DSP_xy ((iword >> 6) & 3);\n");
2560 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2564 if (s
[1] == 'x') /* ax */
2566 printf (" int m = (iword & 3) ? \n");
2567 printf (" 7 - ((iword >> 6) & 2) : \n");
2568 printf (" DSP_ax ((iword >> 6) & 3);\n");
2571 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2575 if (s
[1] == 'X') /* YX */
2577 printf (" int m = (iword & 0xc) ? \n");
2578 printf (" ((iword >> 6) & 1) + 10 : \n");
2579 printf (" DSP_yx ((iword >> 6) & 3);\n");
2582 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2586 if (s
[1] == 'Y') /* AY */
2588 printf (" int m = (iword & 0xc) ? \n");
2589 printf (" 7 - ((iword >> 5) & 2) : \n");
2590 printf (" DSP_ay ((iword >> 6) & 3);\n");
2593 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2598 printf (" int i = (iword & 0x");
2633 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
2634 sextbit
- 1, sextbit
- 1);
2638 printf (" TB (m,n);\n");
2640 printf (" TL (m);\n");
2642 printf (" TL (n);\n");
2647 for (r
= p
->refs
; *r
; r
++)
2649 if (*r
== '0') printf (" CREF (0);\n");
2650 if (*r
== '8') printf (" CREF (8);\n");
2651 if (*r
== '9') printf (" CREF (9);\n");
2652 if (*r
== 'n') printf (" CREF (n);\n");
2653 if (*r
== 'm') printf (" CREF (m);\n");
2658 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2662 printf (" %s\n", p
->stuff
[j
]);
2670 for (r
= p
->defs
; *r
; r
++)
2672 if (*r
== '0') printf(" CDEF (0);\n");
2673 if (*r
== 'n') printf(" CDEF (n);\n");
2674 if (*r
== 'm') printf(" CDEF (m);\n");
2678 printf (" break;\n");
2687 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
2688 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
2689 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
2690 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
2691 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
2692 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
2693 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
2694 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
2695 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
2696 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
2697 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
2698 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
2699 printf (" switch (jump_table[iword]) {\n");
2701 gensim_caselist (tab
);
2702 gensim_caselist (movsxy_tab
);
2704 printf (" default:\n");
2706 printf (" RAISE_EXCEPTION (SIGILL);\n");
2717 for (p
= tab
; p
->name
; p
++)
2720 printf ("#define OPC_");
2734 printf (" %d\n",p
->index
);
2738 static int ppi_index
;
2740 /* Take a ppi code, expand all varying fields in it and fill all the
2741 right entries in 'table' with the opcode index.
2742 NOTE: tail recursion optimization removed for simplicity. */
2745 expand_ppi_code (val
, i
, s
)
2755 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n", s
[0]);
2760 /* The last four bits are disregarded for the switch table. */
2764 /* Four-bit expansion. */
2765 for (j
= 0; j
< 16; j
++)
2766 expand_ppi_code ((val
<< 4) + j
, i
, s
+ 4);
2770 expand_ppi_code ((val
<< 1), i
, s
+ 1);
2773 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
2778 expand_ppi_code ((val
<< 1), i
, s
+ 1);
2779 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
2782 expand_ppi_code ((val
<< 2) + 1, ppi_index
++, s
+ 2);
2783 expand_ppi_code ((val
<< 2) + 2, i
, s
+ 2);
2784 expand_ppi_code ((val
<< 2) + 3, i
, s
+ 2);
2795 for (p
= ppi_tab
; p
->name
; p
++)
2797 p
->index
= ppi_index
++;
2798 expand_ppi_code (0, p
->index
, p
->code
);
2807 printf ("#define DSR_MASK_G 0x80\n");
2808 printf ("#define DSR_MASK_Z 0x40\n");
2809 printf ("#define DSR_MASK_N 0x20\n");
2810 printf ("#define DSR_MASK_V 0x10\n");
2812 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2813 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2814 printf (" if (overflow && S) \\\n");
2816 printf (" if (res_grd & 0x80) \\\n");
2818 printf (" res = 0x80000000; \\\n");
2819 printf (" res_grd |= 0xff; \\\n");
2821 printf (" else \\\n");
2823 printf (" res = 0x7fffffff; \\\n");
2824 printf (" res_grd &= ~0xff; \\\n");
2826 printf (" overflow = 0; \\\n");
2828 printf ("} while (0)\n");
2830 printf ("#define ADD_SUB_GE \\\n");
2831 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2833 printf ("static void\n");
2834 printf ("ppi_insn (iword)\n");
2835 printf (" int iword;\n");
2837 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
2838 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2839 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
2840 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2841 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
2842 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2843 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
2844 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2845 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
2846 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2847 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
2848 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2850 printf (" int z;\n");
2851 printf (" int res, res_grd;\n");
2852 printf (" int carry, overflow, greater_equal;\n");
2854 printf (" switch (ppi_table[iword >> 4]) {\n");
2856 for (; p
->name
; p
++)
2864 printf (" /* %s %s */\n", p
->name
, p
->code
);
2865 printf (" case %d: \n", p
->index
);
2868 for (shift
= 16; *s
; )
2873 printf (" int i = (iword >> 4) & 0x7f;\n");
2883 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2889 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2890 printf ("\treturn;\n");
2892 printf (" case %d: \n", p
->index
+ 1);
2904 printf (" z = iword & 0xf;\n");
2912 else if (havedecl
== 2)
2914 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2919 (havedecl
== 2 ? " " : ""),
2927 printf (" if (iword & 0x200)\n");
2928 printf (" goto assign_z;\n");
2930 printf (" break;\n");
2934 printf (" default:\n");
2936 printf (" RAISE_EXCEPTION (SIGILL);\n");
2937 printf (" return;\n");
2940 printf (" DSR &= ~0xf1;\n");
2941 printf (" if (res || res_grd)\n");
2942 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2944 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2945 printf (" assign_dc:\n");
2946 printf (" switch (DSR >> 1 & 7)\n");
2948 printf (" case 0: /* Carry Mode */\n");
2949 printf (" DSR |= carry;\n");
2950 printf (" case 1: /* Negative Value Mode */\n");
2951 printf (" DSR |= res_grd >> 7 & 1;\n");
2952 printf (" case 2: /* Zero Value Mode */\n");
2953 printf (" DSR |= DSR >> 6 & 1;\n");
2954 printf (" case 3: /* Overflow mode\n");
2955 printf (" DSR |= overflow >> 4;\n");
2956 printf (" case 4: /* Signed Greater Than Mode */\n");
2957 printf (" DSR |= DSR >> 7 & 1;\n");
2958 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2959 printf (" DSR |= greater_equal >> 7;\n");
2961 printf (" assign_z:\n");
2962 printf (" if (0xa05f >> z & 1)\n");
2964 printf (" RAISE_EXCEPTION (SIGILL);\n");
2965 printf (" return;\n");
2967 printf (" DSP_R (z) = res;\n");
2968 printf (" DSP_GRD (z) = res_grd;\n");
2977 /* Verify the table before anything else. */
2980 for (p
= tab
; p
->name
; p
++)
2982 /* Check that the code field contains 16 bits. */
2983 if (strlen (p
->code
) != 16)
2985 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2986 p
->code
, strlen (p
->code
), p
->name
);
2992 /* Now generate the requested data. */
2995 if (strcmp (av
[1], "-t") == 0)
2999 else if (strcmp (av
[1], "-d") == 0)
3003 else if (strcmp (av
[1], "-s") == 0)
3006 dumptable ("sh_jump_table", 1 << 16, 0);
3008 memset (table
, 0, sizeof table
);
3009 filltable (movsxy_tab
);
3010 expand_ppi_movxy ();
3011 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3013 memset (table
, 0, sizeof table
);
3015 dumptable ("ppi_table", 1 << 12, 0);
3017 else if (strcmp (av
[1], "-x") == 0)
3020 filltable (movsxy_tab
);
3023 else if (strcmp (av
[1], "-p") == 0)
3030 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.149382 seconds and 5 git commands to generate.