52e611f3698a4951390d15ff43c664dc16af0376
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", "", "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 { "", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
205 "div1 (R, 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));",
446 /* sh4: See fmov instructions above for move to/from extended fp registers */
449 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
454 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
459 { "", "", "fpchg", "1111011111111101",
460 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
464 { "", "", "frchg", "1111101111111101",
466 " RAISE_EXCEPTION (SIGILL);",
468 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
472 { "", "", "fsca", "1111eeee11111101",
474 " RAISE_EXCEPTION (SIGILL);",
477 " SET_FR (n, fsca_s (FPUL, &sin));",
478 " SET_FR (n+1, fsca_s (FPUL, &cos));",
483 { "", "", "fschg", "1111001111111101",
484 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
488 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
489 "FP_UNARY (n, sqrt);",
493 { "", "", "fsrra", "1111nnnn01111101",
495 " RAISE_EXCEPTION (SIGILL);",
497 " SET_FR (n, fsrra_s (FR (n)));",
501 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
506 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
509 " if (DR (n) != DR (n)) /* NaN */",
510 " FPUL = 0x80000000;",
512 " FPUL = (int) DR (n);",
515 "if (FR (n) != FR (n)) /* NaN */",
516 " FPUL = 0x80000000;",
518 " FPUL = (int) FR (n);",
522 { "", "", "ftrv <FV_N>", "1111vv0111111101",
524 " RAISE_EXCEPTION (SIGILL);",
527 " /* FIXME not implemented. */",
528 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
533 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
543 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
544 "SET_NIP (PT2H (R[n]));",
546 "Delay_Slot (PC + 2);",
549 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
550 "PR = PH2T (PC + 4);",
552 " gotcall (PR, R[n]);",
553 "SET_NIP (PT2H (R[n]));",
555 "Delay_Slot (PC + 2);",
558 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
560 "/* FIXME: user mode */",
562 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
564 "/* FIXME: user mode */",
566 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
569 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
571 " DBR = R[n]; /* priv mode */",
573 " RAISE_EXCEPTION (SIGILL); /* user mode */",
575 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
577 " SGR = R[n]; /* priv mode */",
579 " RAISE_EXCEPTION (SIGILL); /* user mode */",
581 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
583 "CREG (m) = RLAT (R[n]);",
585 "/* FIXME: user mode */",
587 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
589 "SET_SR (RLAT (R[n]));",
591 "/* FIXME: user mode */",
593 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
595 "SET_MOD (RLAT (R[n]));",
598 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
602 " DBR = RLAT (R[n]);",
606 " RAISE_EXCEPTION (SIGILL); /* user mode */",
608 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
612 " SGR = RLAT (R[n]);",
616 " RAISE_EXCEPTION (SIGILL); /* user mode */",
620 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
621 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
623 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
624 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
628 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
630 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
631 "CHECK_INSN_PTR (insn_ptr);",
634 { "", "", "ldrc #<imm>", "10001010i8*1....",
636 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
637 "CHECK_INSN_PTR (insn_ptr);",
641 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
644 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
646 "SREG (m) = RLAT (R[n]);",
649 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
650 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
653 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
654 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
656 "SET_FPSCR (RLAT (R[n]));",
660 { "", "", "ldtlb", "0000000000111000",
661 "/* We don't implement cache or tlb, so this is a noop. */",
664 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
665 "macl (&R0,memory,n,m);",
668 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
669 "macw (&R0,memory,n,m,endianw);",
672 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
675 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
679 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
681 "R0 = RSBAT (i + GBR);",
684 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
686 "R0 = RSBAT (i + R[m]);",
689 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
691 "R[n] = RSBAT (R0 + R[m]);",
694 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
696 "R[n] = RSBAT (R[m]);",
700 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
702 "WBAT (R[n], R[m]);",
704 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
706 "WBAT (i + GBR, R0);",
708 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
710 "WBAT (i + R[m], R0);",
712 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
714 "WBAT (R[n] + R0, R[m]);",
716 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
719 "WBAT (R[n], R[m]);",
721 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
723 "R[n] = RSBAT (R[m]);",
727 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
729 "R0 = RLAT (i + GBR);",
732 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
734 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
737 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
739 "R[n] = RLAT (i + R[m]);",
742 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
744 "R[n] = RLAT (R0 + R[m]);",
747 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
749 "R[n] = RLAT (R[m]);",
753 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
755 "R[n] = RLAT (R[m]);",
758 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
760 "WLAT (i + GBR, R0);",
762 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
764 "WLAT (i + R[n], R[m]);",
766 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
768 "WLAT (R0 + R[n], R[m]);",
770 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
773 "WLAT (R[n], R[m]);",
775 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
777 "WLAT (R[n], R[m]);",
780 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
782 "R0 = RSWAT (i + GBR);",
785 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
787 "R[n] = RSWAT (PH2T (PC + 4 + i));",
790 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
792 "R0 = RSWAT (i + R[m]);",
795 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
797 "R[n] = RSWAT (R0 + R[m]);",
800 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
802 "R[n] = RSWAT (R[m]);",
806 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
808 "R[n] = RSWAT (R[m]);",
811 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
813 "WWAT (i + GBR, R0);",
815 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
817 "WWAT (i + R[m], R0);",
819 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
821 "WWAT (R0 + R[n], R[m]);",
823 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
826 "WWAT (R[n], R[m]);",
828 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
830 "WWAT (R[n], R[m]);",
833 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
834 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
837 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
838 "/* We don't simulate cache, so this insn is identical to mov. */",
840 "WLAT (R[n], R[0]);",
843 { "n", "0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
846 "/* if (T) R0 -> (Rn) */",
848 " WLAT (R[n], R[0]);",
853 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
857 "R[0] = RLAT (R[n]);",
858 "/* if (interrupt/exception) 0 -> LDST */",
859 "/* (we don't simulate asynchronous interrupts/exceptions) */",
862 { "n", "", "movt <REG_N>", "0000nnnn00101001",
866 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
869 "R[0] = (RBAT (regn) << 24) + (RBAT (regn + 1) << 16) + ",
870 " (RBAT (regn + 2) << 8) + RBAT (regn + 3);",
873 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
876 "R[0] = (RBAT (regn) << 24) + (RBAT (regn + 1) << 16) + ",
877 " (RBAT (regn + 2) << 8) + RBAT (regn + 3);",
881 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
882 "MACL = ((int) R[n]) * ((int) R[m]);",
884 #if 0 /* FIXME: The above cast to int is not really portable.
885 It should be replaced by a SEXT32 macro. */
886 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
887 "MACL = R[n] * R[m];",
891 /* muls.w - see muls */
892 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
893 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
896 /* mulu.w - see mulu */
897 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
898 "MACL = (((unsigned int) (unsigned short) R[n])",
899 " * ((unsigned int) (unsigned short) R[m]));",
902 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
906 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
908 "SET_SR_T (ult > 0);",
909 "R[n] = ult - R[m];",
910 "SET_SR_T (T || (R[n] > ult));",
913 { "", "", "nop", "0000000000001001",
917 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
922 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
923 "/* Except for the effect on the cache - which is not simulated -",
924 " this is like a nop. */",
927 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
928 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
929 "/* FIXME: Cache not implemented */",
932 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
933 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
934 "/* FIXME: Cache not implemented */",
937 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
938 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
939 "/* FIXME: Cache not implemented */",
942 { "0", "", "or #<imm>,R0", "11001011i8*1....",
945 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
948 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
950 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
953 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
954 "/* Except for the effect on the cache - which is not simulated -",
955 " this is like a nop. */",
959 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
960 "/* Except for the effect on the cache - which is not simulated -",
961 " this is like a nop. */",
965 { "", "", "synco", "0000000010101011",
966 "/* Except for the effect on the pipeline - which is not simulated -",
967 " this is like a nop. */",
970 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
972 "R[n] = (R[n] << 1) | T;",
976 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
978 "R[n] = (UR[n] >> 1) | (T << 31);",
982 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
983 "SET_SR_T (R[n] < 0);",
988 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
989 "SET_SR_T (R[n] & 1);",
990 "R[n] = UR[n] >> 1;",
991 "R[n] |= (T << 31);",
994 { "", "", "rte", "0000000000101011",
998 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1000 "SET_SR (RLAT (R[15]) & 0x3f3);",
1002 "Delay_Slot (PC + 2);",
1005 "SET_NIP (PT2H (SPC));",
1007 "Delay_Slot (PC + 2);",
1011 { "", "", "rts", "0000000000001011",
1012 "SET_NIP (PT2H (PR));",
1014 "Delay_Slot (PC + 2);",
1018 { "", "", "setdmx", "0000000010011000",
1019 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1020 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1024 { "", "", "setdmy", "0000000011001000",
1025 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1026 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1030 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1033 { "", "", "setrc #<imm>", "10000010i8*1....",
1034 /* It would be more realistic to let loop_start point to some static
1035 memory that contains an illegal opcode and then give a bus error when
1036 the loop is eventually encountered, but it seems not only simpler,
1037 but also more debugging-friendly to just catch the failure here. */
1038 "if (BUSERROR (RS | RE, maskw))",
1039 " RAISE_EXCEPTION (SIGILL);",
1042 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1043 " CHECK_INSN_PTR (insn_ptr);",
1047 { "", "", "sets", "0000000001011000",
1051 { "", "", "sett", "0000000000011000",
1055 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1056 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
1059 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1060 "SET_SR_T (R[n] < 0);",
1064 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1065 "SET_SR_T (R[n] & 1);",
1066 "R[n] = R[n] >> 1;",
1069 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1070 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
1073 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1074 "SET_SR_T (R[n] < 0);",
1078 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1081 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1084 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1088 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1089 "SET_SR_T (R[n] & 1);",
1090 "R[n] = UR[n] >> 1;",
1093 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1094 "R[n] = UR[n] >> 2;",
1096 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1097 "R[n] = UR[n] >> 8;",
1099 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1100 "R[n] = UR[n] >> 16;",
1103 { "", "", "sleep", "0000000000011011",
1104 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
1107 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1111 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1113 " R[n] = SGR; /* priv mode */",
1115 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1117 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1119 " R[n] = DBR; /* priv mode */",
1121 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1123 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1126 "WLAT (R[n], CREG (m));",
1128 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1130 "{ /* priv mode */",
1133 " WLAT (R[n], SGR);",
1136 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1138 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1140 "{ /* priv mode */",
1143 " WLAT (R[n], DBR);",
1146 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1149 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1152 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1155 "WLAT (R[n], SREG (m));",
1158 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1162 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1164 "SET_SR_T (ult > R[n]);",
1165 "R[n] = ult - R[m];",
1166 "SET_SR_T (T || (R[n] > ult));",
1169 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1170 "ult = R[n] - R[m];",
1171 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1175 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1176 "R[n] = ((R[m] & 0xffff0000)",
1177 " | ((R[m] << 8) & 0xff00)",
1178 " | ((R[m] >> 8) & 0x00ff));",
1180 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1181 "R[n] = (((R[m] << 16) & 0xffff0000)",
1182 " | ((R[m] >> 16) & 0x00ffff));",
1185 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1187 "ult = RBAT (R[n]);",
1188 "SET_SR_T (ult == 0);",
1189 "WBAT (R[n],ult|0x80);",
1192 { "0", "", "trapa #<imm>", "11000011i8*1....",
1193 "long imm = 0xff & i;",
1194 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1195 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1200 " WLAT (R[15], GET_SR ());",
1202 " WLAT (R[15], PH2T (PC + 2));",
1204 "else if (!SR_BL) {",
1205 " SSR = GET_SR ();",
1206 " SPC = PH2T (PC + 2);",
1207 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1208 " /* FIXME: EXPEVT = 0x00000160; */",
1210 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1214 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1215 "SET_SR_T ((R[n] & R[m]) == 0);",
1217 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1218 "SET_SR_T ((R0 & i) == 0);",
1220 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1222 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1225 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1228 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1231 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1233 "ult = RBAT (GBR+R0);",
1235 "WBAT (GBR + R0, ult);",
1238 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1239 "R[n] = (((R[n] >> 16) & 0xffff)",
1240 " | ((R[m] << 16) & 0xffff0000));",
1244 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1245 "divl (0,R[n],R[m]);",
1247 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1248 "divl (0,R[n],R[m]);",
1256 /* If this is disabled, the simulator speeds up by about 12% on a
1257 450 MHz PIII - 9% with ACE_FAST.
1258 Maybe we should have separate simulator loops? */
1260 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1263 "DSP_R (m) = RSWAT (R[n]) << 16;",
1264 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1266 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1268 "DSP_R (m) = RSWAT (R[n]) << 16;",
1269 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1271 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1273 "DSP_R (m) = RSWAT (R[n]) << 16;",
1274 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1277 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1279 "DSP_R (m) = RSWAT (R[n]) << 16;",
1280 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1283 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1286 "DSP_R (m) = RSWAT (R[n]);",
1288 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1290 "DSP_R (m) = RSWAT (R[n]);",
1292 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1294 "DSP_R (m) = RSWAT (R[n]);",
1297 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1299 "DSP_R (m) = RSWAT (R[n]);",
1302 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1305 "WWAT (R[n], DSP_R (m) >> 16);",
1307 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1309 "WWAT (R[n], DSP_R (m) >> 16);",
1311 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1313 "WWAT (R[n], DSP_R (m) >> 16);",
1316 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1318 "WWAT (R[n], DSP_R (m) >> 16);",
1321 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1324 "WWAT (R[n], SEXT (DSP_R (m)));",
1326 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1328 "WWAT (R[n], SEXT (DSP_R (m)));",
1330 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1332 "WWAT (R[n], SEXT (DSP_R (m)));",
1335 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1337 "WWAT (R[n], SEXT (DSP_R (m)));",
1340 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1343 "DSP_R (m) = RLAT (R[n]);",
1344 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1346 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1348 "DSP_R (m) = RLAT (R[n]);",
1349 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1351 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1353 "DSP_R (m) = RLAT (R[n]);",
1354 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1357 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1359 "DSP_R (m) = RLAT (R[n]);",
1360 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1363 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1366 "WLAT (R[n], DSP_R (m));",
1368 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1370 "WLAT (R[n], DSP_R (m));",
1372 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1374 "WLAT (R[n], DSP_R (m));",
1377 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1379 "WLAT (R[n], DSP_R (m));",
1382 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1385 "WLAT (R[n], SEXT (DSP_R (m)));",
1387 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1389 "WLAT (R[n], SEXT (DSP_R (m)));",
1391 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1393 "WLAT (R[n], SEXT (DSP_R (m)));",
1396 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1398 "WLAT (R[n], SEXT (DSP_R (m)));",
1401 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1402 "DSP_R (m) = RSWAT (R[n]) << 16;",
1405 " iword &= 0xfd53; goto top;",
1408 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1409 "DSP_R (m) = RLAT (R[n]);",
1411 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1412 "DSP_R (m) = RSWAT (R[n]) << 16;",
1413 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1416 " iword &= 0xfd53; goto top;",
1419 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1420 "DSP_R (m) = RLAT (R[n]);",
1421 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1423 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1424 "DSP_R (m) = RSWAT (R[n]) << 16;",
1425 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1428 " iword &= 0xfd53; goto top;",
1431 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1432 "DSP_R (m) = RLAT (R[n]);",
1433 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1435 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1436 "WWAT (R[n], DSP_R (m) >> 16);",
1439 " iword &= 0xfd53; goto top;",
1442 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1443 "WLAT (R[n], DSP_R (m));",
1445 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1446 "WWAT (R[n], DSP_R (m) >> 16);",
1447 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1450 " iword &= 0xfd53; goto top;",
1453 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1454 "WLAT (R[n], DSP_R (m));",
1455 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1457 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1458 "WWAT (R[n], DSP_R (m) >> 16);",
1459 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1462 " iword &= 0xfd53; goto top;",
1465 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1466 "WLAT (R[n], DSP_R (m));",
1467 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1469 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1470 "DSP_R (m) = RSWAT (R[n]) << 16;",
1472 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1473 "DSP_R (m) = RSWAT (R[n]) << 16;",
1474 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1476 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1477 "DSP_R (m) = RSWAT (R[n]) << 16;",
1478 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1480 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1481 "WWAT (R[n], DSP_R (m) >> 16);",
1483 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1484 "WWAT (R[n], DSP_R (m) >> 16);",
1485 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1487 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1488 "WWAT (R[n], DSP_R (m) >> 16);",
1489 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1491 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1492 "DSP_R (m) = RLAT (R[n]);",
1494 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1495 "DSP_R (m) = RLAT (R[n]);",
1496 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1498 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1499 "DSP_R (m) = RLAT (R[n]);",
1500 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1502 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1503 "WLAT (R[n], DSP_R (m));",
1505 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1506 "WLAT (R[n], DSP_R (m));",
1507 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1509 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1510 "WLAT (R[n], DSP_R (m));",
1511 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1513 { "", "", "nopx nopy", "1111000000000000",
1516 { "", "", "ppi", "1111100000000000",
1517 "ppi_insn (RIAT (nip));",
1519 "iword &= 0xf7ff; goto top;",
1526 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1527 "int Sz = DSP_R (z) & 0xffff0000;",
1531 "else if (i >= 128 - 16)",
1532 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1535 " RAISE_EXCEPTION (SIGILL);",
1538 "res &= 0xffff0000;",
1542 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1543 "int Sz = DSP_R (z);",
1544 "int Sz_grd = GET_DSP_GRD (z);",
1556 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1558 " res_grd = SEXT (res_grd);",
1559 " carry = res_grd & 1;",
1561 "else if (i >= 96)",
1566 " res_grd = SIGN32 (Sz_grd);",
1571 " res = Sz >> i | Sz_grd << 32 - i;",
1572 " res_grd = Sz_grd >> i;",
1574 " carry = Sz >> (i - 1) & 1;",
1578 " RAISE_EXCEPTION (SIGILL);",
1581 "COMPUTE_OVERFLOW;",
1582 "greater_equal = 0;",
1584 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1585 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1586 "if (res == 0x80000000)",
1587 " res = 0x7fffffff;",
1589 "DSP_GRD (g) = SIGN32 (res);",
1592 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1593 "int Sx = DSP_R (x);",
1594 "int Sx_grd = GET_DSP_GRD (x);",
1595 "int Sy = DSP_R (y);",
1596 "int Sy_grd = SIGN32 (Sy);",
1598 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1599 "if (res == 0x80000000)",
1600 " res = 0x7fffffff;",
1602 "DSP_GRD (g) = SIGN32 (res);",
1606 "carry = (unsigned) res > (unsigned) Sx;",
1607 "res_grd = Sx_grd - Sy_grd - carry;",
1608 "COMPUTE_OVERFLOW;",
1611 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1612 "int Sx = DSP_R (x);",
1613 "int Sx_grd = GET_DSP_GRD (x);",
1614 "int Sy = DSP_R (y);",
1615 "int Sy_grd = SIGN32 (Sy);",
1617 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1618 "if (res == 0x80000000)",
1619 " res = 0x7fffffff;",
1621 "DSP_GRD (g) = SIGN32 (res);",
1625 "carry = (unsigned) res < (unsigned) Sx;",
1626 "res_grd = Sx_grd + Sy_grd + carry;",
1627 "COMPUTE_OVERFLOW;",
1629 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1630 "int Sx = DSP_R (x);",
1631 "int Sx_grd = GET_DSP_GRD (x);",
1632 "int Sy = DSP_R (y);",
1633 "int Sy_grd = SIGN32 (Sy);",
1635 "res = Sx - Sy - (DSR & 1);",
1636 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1637 "res_grd = Sx_grd + Sy_grd + carry;",
1638 "COMPUTE_OVERFLOW;",
1641 "if (res || res_grd)\n",
1642 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1644 " DSR |= DSR_MASK_Z | overflow;\n",
1648 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1649 "int Sx = DSP_R (x);",
1650 "int Sx_grd = GET_DSP_GRD (x);",
1651 "int Sy = DSP_R (y);",
1652 "int Sy_grd = SIGN32 (Sy);",
1654 "res = Sx + Sy + (DSR & 1);",
1655 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1656 "res_grd = Sx_grd + Sy_grd + carry;",
1657 "COMPUTE_OVERFLOW;",
1660 "if (res || res_grd)\n",
1661 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1663 " DSR |= DSR_MASK_Z | overflow;\n",
1667 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1668 "int Sx = DSP_R (x);",
1669 "int Sx_grd = GET_DSP_GRD (x);",
1670 "int Sy = DSP_R (y);",
1671 "int Sy_grd = SIGN32 (Sy);",
1673 "z = 17; /* Ignore result. */",
1675 "carry = (unsigned) res > (unsigned) Sx;",
1676 "res_grd = Sx_grd - Sy_grd - carry;",
1677 "COMPUTE_OVERFLOW;",
1680 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1682 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1684 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
1685 "/* FIXME: duplicate code pabs. */",
1687 "res_grd = GET_DSP_GRD (x);",
1693 " carry = (res != 0); /* The manual has a bug here. */",
1694 " res_grd = -res_grd - carry;",
1696 "COMPUTE_OVERFLOW;",
1697 "/* ??? The re-computing of overflow after",
1698 " saturation processing is specific to pabs. */",
1699 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1702 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1704 "res_grd = GET_DSP_GRD (x);",
1710 " carry = (res != 0); /* The manual has a bug here. */",
1711 " res_grd = -res_grd - carry;",
1713 "COMPUTE_OVERFLOW;",
1714 "/* ??? The re-computing of overflow after",
1715 " saturation processing is specific to pabs. */",
1716 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1720 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
1721 "/* FIXME: duplicate code prnd. */",
1722 "int Sx = DSP_R (x);",
1723 "int Sx_grd = GET_DSP_GRD (x);",
1725 "res = (Sx + 0x8000) & 0xffff0000;",
1726 "carry = (unsigned) res < (unsigned) Sx;",
1727 "res_grd = Sx_grd + carry;",
1728 "COMPUTE_OVERFLOW;",
1731 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1732 "int Sx = DSP_R (x);",
1733 "int Sx_grd = GET_DSP_GRD (x);",
1735 "res = (Sx + 0x8000) & 0xffff0000;",
1736 "carry = (unsigned) res < (unsigned) Sx;",
1737 "res_grd = Sx_grd + carry;",
1738 "COMPUTE_OVERFLOW;",
1742 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
1743 "/* FIXME: duplicate code pabs. */",
1747 "greater_equal = DSR_MASK_G;",
1757 " res = 0x7fffffff;",
1760 " overflow = DSR_MASK_V;",
1761 " greater_equal = 0;",
1766 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1770 "greater_equal = DSR_MASK_G;",
1780 " res = 0x7fffffff;",
1783 " overflow = DSR_MASK_V;",
1784 " greater_equal = 0;",
1789 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
1790 "/* FIXME: duplicate code prnd. */",
1791 "int Sy = DSP_R (y);",
1792 "int Sy_grd = SIGN32 (Sy);",
1794 "res = (Sy + 0x8000) & 0xffff0000;",
1795 "carry = (unsigned) res < (unsigned) Sy;",
1796 "res_grd = Sy_grd + carry;",
1797 "COMPUTE_OVERFLOW;",
1800 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1801 "int Sy = DSP_R (y);",
1802 "int Sy_grd = SIGN32 (Sy);",
1804 "res = (Sy + 0x8000) & 0xffff0000;",
1805 "carry = (unsigned) res < (unsigned) Sy;",
1806 "res_grd = Sy_grd + carry;",
1807 "COMPUTE_OVERFLOW;",
1810 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1811 "int Sx = DSP_R (x) & 0xffff0000;",
1812 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1816 "else if (Sy >= 128 - 16)",
1817 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
1820 " RAISE_EXCEPTION (SIGILL);",
1823 "goto cond_logical;",
1825 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1826 "int Sx = DSP_R (x);",
1827 "int Sx_grd = GET_DSP_GRD (x);",
1828 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1840 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1842 " res_grd = SEXT (res_grd);",
1843 " carry = res_grd & 1;",
1845 "else if (Sy >= 96)",
1850 " res_grd = SIGN32 (Sx_grd);",
1855 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1856 " res_grd = Sx_grd >> Sy;",
1858 " carry = Sx >> (Sy - 1) & 1;",
1862 " RAISE_EXCEPTION (SIGILL);",
1865 "COMPUTE_OVERFLOW;",
1866 "greater_equal = 0;",
1868 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1869 "int Sx = DSP_R (x);",
1870 "int Sx_grd = GET_DSP_GRD (x);",
1871 "int Sy = DSP_R (y);",
1872 "int Sy_grd = SIGN32 (Sy);",
1875 "carry = (unsigned) res > (unsigned) Sx;",
1876 "res_grd = Sx_grd - Sy_grd - carry;",
1877 "COMPUTE_OVERFLOW;",
1880 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
1881 "int Sx = DSP_R (x);",
1882 "int Sx_grd = GET_DSP_GRD (x);",
1883 "int Sy = DSP_R (y);",
1884 "int Sy_grd = SIGN32 (Sy);",
1887 "carry = (unsigned) res > (unsigned) Sy;",
1888 "res_grd = Sy_grd - Sx_grd - carry;",
1889 "COMPUTE_OVERFLOW;",
1892 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1893 "int Sx = DSP_R (x);",
1894 "int Sx_grd = GET_DSP_GRD (x);",
1895 "int Sy = DSP_R (y);",
1896 "int Sy_grd = SIGN32 (Sy);",
1899 "carry = (unsigned) res < (unsigned) Sx;",
1900 "res_grd = Sx_grd + Sy_grd + carry;",
1901 "COMPUTE_OVERFLOW;",
1904 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1905 "res = DSP_R (x) & DSP_R (y);",
1907 "res &= 0xffff0000;",
1909 "if (iword & 0x200)\n",
1910 " goto assign_z;\n",
1914 "greater_equal = 0;",
1917 " DSR |= res >> 26 & DSR_MASK_N;\n",
1919 " DSR |= DSR_MASK_Z;\n",
1920 "goto assign_dc;\n",
1922 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1923 "res = DSP_R (x) ^ DSP_R (y);",
1924 "goto cond_logical;",
1926 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1927 "res = DSP_R (x) | DSP_R (y);",
1928 "goto cond_logical;",
1930 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1931 "int Sx = DSP_R (x);",
1932 "int Sx_grd = GET_DSP_GRD (x);",
1934 "res = Sx - 0x10000;",
1935 "carry = res > Sx;",
1936 "res_grd = Sx_grd - carry;",
1937 "COMPUTE_OVERFLOW;",
1939 "res &= 0xffff0000;",
1941 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1942 "int Sx = DSP_R (x);",
1943 "int Sx_grd = GET_DSP_GRD (x);",
1945 "res = Sx + 0x10000;",
1946 "carry = res < Sx;",
1947 "res_grd = Sx_grd + carry;",
1948 "COMPUTE_OVERFLOW;",
1950 "res &= 0xffff0000;",
1952 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1953 "int Sy = DSP_R (y);",
1954 "int Sy_grd = SIGN32 (Sy);",
1956 "res = Sy - 0x10000;",
1957 "carry = res > Sy;",
1958 "res_grd = Sy_grd - carry;",
1959 "COMPUTE_OVERFLOW;",
1961 "res &= 0xffff0000;",
1963 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1964 "int Sy = DSP_R (y);",
1965 "int Sy_grd = SIGN32 (Sy);",
1967 "res = Sy + 0x10000;",
1968 "carry = res < Sy;",
1969 "res_grd = Sy_grd + carry;",
1970 "COMPUTE_OVERFLOW;",
1972 "res &= 0xffff0000;",
1974 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1979 "greater_equal = 1;",
1981 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
1982 "/* Do multiply. */",
1983 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1984 "if (res == 0x80000000)",
1985 " res = 0x7fffffff;",
1987 "DSP_GRD (g) = SIGN32 (res);",
1988 "/* FIXME: update DSR based on results of multiply! */",
1996 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1997 "unsigned Sx = DSP_R (x);",
1998 "int Sx_grd = GET_DSP_GRD (x);",
2003 " Sx_grd = ~Sx_grd;",
2017 " if (Sx & ~0 << i)",
2025 "res_grd = SIGN32 (res);",
2030 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2031 "unsigned Sy = DSP_R (y);",
2040 " if (Sy & ~0 << i)",
2048 "res_grd = SIGN32 (res);",
2053 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2054 "int Sx = DSP_R (x);",
2055 "int Sx_grd = GET_DSP_GRD (x);",
2058 "carry = res != 0;",
2059 "res_grd = 0 - Sx_grd - carry;",
2060 "COMPUTE_OVERFLOW;",
2063 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2065 "res_grd = GET_DSP_GRD (x);",
2067 "COMPUTE_OVERFLOW;",
2070 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2071 "int Sy = DSP_R (y);",
2072 "int Sy_grd = SIGN32 (Sy);",
2075 "carry = res != 0;",
2076 "res_grd = 0 - Sy_grd - carry;",
2077 "COMPUTE_OVERFLOW;",
2080 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2082 "res_grd = SIGN32 (res);",
2084 "COMPUTE_OVERFLOW;",
2087 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2089 "res_grd = SIGN32 (res);",
2092 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2094 "res_grd = SIGN32 (res);",
2097 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2098 "if (0xa05f >> z & 1)",
2099 " RAISE_EXCEPTION (SIGILL);",
2101 " MACH = DSP_R (z);",
2104 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2105 "if (0xa05f >> z & 1)",
2106 " RAISE_EXCEPTION (SIGILL);",
2108 " MACL = DSP_R (z) = res;",
2112 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2113 "int Sx = DSP_R (x);",
2115 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2116 "res_grd = GET_DSP_GRD (x);",
2119 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2122 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2123 "int Sy = DSP_R (y);",
2125 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2126 "res_grd = SIGN32 (Sy);",
2129 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2135 /* Tables of things to put into enums for sh-opc.h */
2136 static char *nibble_type_list
[] =
2171 char *arg_type_list
[] =
2205 make_enum_list (name
, s
)
2210 printf ("typedef enum {\n");
2213 printf ("\t%s,\n", *s
);
2217 printf ("} %s;\n", name
);
2229 memcpy (bufa
, a
->code
, 4);
2230 memcpy (bufa
+ 4, a
->code
+ 12, 4);
2233 memcpy (bufb
, b
->code
, 4);
2234 memcpy (bufb
+ 4, b
->code
+ 12, 4);
2236 diff
= strcmp (bufa
, bufb
);
2237 /* Stabilize the sort, so that later entries can override more general
2238 preceding entries. */
2239 return diff
? diff
: a
- b
;
2253 qsort (tab
, len
, sizeof (*p
), qfunc
);
2261 for (p
= tab
; p
->name
; p
++)
2263 printf ("%s %-30s\n", p
->code
, p
->name
);
2269 static unsigned char table
[1 << 16];
2271 /* Take an opcode, expand all varying fields in it out and fill all the
2272 right entries in 'table' with the opcode index. */
2275 expand_opcode (val
, i
, s
)
2291 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
2295 /* Consume an arbitrary number of ones and zeros. */
2297 j
= (j
<< 1) + (s
[m
++] - '0');
2298 } while (s
[m
] == '0' || s
[m
] == '1');
2299 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
2301 case 'N': /* NN -- four-way fork */
2302 for (j
= 0; j
< 4; j
++)
2303 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2305 case 'x': /* xx or xy -- two-way or four-way fork */
2306 for (j
= 0; j
< 4; j
+= (s
[1] == 'x' ? 2 : 1))
2307 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2309 case 'y': /* yy or yx -- two-way or four-way fork */
2310 for (j
= 0; j
< (s
[1] == 'x' ? 4 : 2); j
++)
2311 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2313 case '?': /* Seven-way "wildcard" fork for movxy */
2314 expand_opcode ((val
<< 2), i
, s
+ 2);
2315 for (j
= 1; j
< 4; j
++)
2317 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2318 expand_opcode ((val
<< 2) | (j
+ 16), i
, s
+ 2);
2321 case 'i': /* eg. "i8*1" */
2322 case '.': /* "...." is a wildcard */
2325 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2326 for (j
= 0; j
< 16; j
++)
2327 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2330 /* eeee -- even numbered register:
2332 for (j
= 0; j
< 15; j
+= 2)
2333 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2336 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2337 MMMM -- 10-way fork */
2338 expand_opcode ((val
<< 4) | 5, i
, s
+ 4);
2339 for (j
= 7; j
< 16; j
++)
2340 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2344 GGGG -- two-way fork */
2345 for (j
= 13; j
<= 15; j
+=2)
2346 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2349 /* ssss -- 10-way fork */
2350 /* System registers mach, macl, pr: */
2351 for (j
= 0; j
< 3; j
++)
2352 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2353 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2354 for (j
= 5; j
< 12; j
++)
2355 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2358 /* XX/XY -- 2/4 way fork. */
2359 for (j
= 0; j
< 4; j
+= (s
[1] == 'X' ? 2 : 1))
2360 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2363 /* aa/ax -- 2/4 way fork. */
2364 for (j
= 0; j
< 4; j
+= (s
[1] == 'a' ? 2 : 1))
2365 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2368 /* YY/YX -- 2/4 way fork. */
2369 for (j
= 0; j
< (s
[1] == 'Y' ? 2 : 4); j
+= 1)
2370 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2373 /* AA/AY: 2/4 way fork. */
2374 for (j
= 0; j
< (s
[1] == 'A' ? 2 : 4); j
+= 1)
2375 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2378 /* vv(VV) -- 4(16) way fork. */
2379 /* Vector register fv0/4/8/12. */
2382 /* 2 vector registers. */
2383 for (j
= 0; j
< 15; j
++)
2384 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2388 /* 1 vector register. */
2389 for (j
= 0; j
< 4; j
+= 1)
2390 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2397 /* Print the jump table used to index an opcode into a switch
2401 dumptable (name
, size
, start
)
2411 printf ("unsigned char %s[%d]={\n", name
, size
);
2412 while (i
< start
+ size
)
2416 printf ("/* 0x%x */\n", i
);
2423 printf ("%2d", table
[i
+ j
+ k
]);
2442 static int index
= 1;
2445 for (; p
->name
; p
++)
2448 expand_opcode (0, p
->index
, p
->code
);
2452 /* Table already contains all the switch case tags for 16-bit opcode double
2453 data transfer (ddt) insns, and the switch case tag for processing parallel
2454 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2455 latter tag to represent all combinations of ppi with ddt. */
2461 for (i
= 0xf000; i
< 0xf400; i
++)
2463 table
[i
+ 0x800] = table
[0xf800];
2470 for (; p
->name
; p
++)
2479 printf (" /* %s %s */\n", p
->name
, p
->code
);
2480 printf (" case %d: \n", p
->index
);
2488 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2493 /* Wildcard expansion, nothing to do here. */
2497 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2501 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2513 printf (" int n = (iword >> 8) & 0xf;\n");
2518 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2522 if (s
[1] == 'y') /* xy */
2524 printf (" int n = (iword & 3) ? \n");
2525 printf (" ((iword >> 9) & 1) + 4 : \n");
2526 printf (" REG_xy ((iword >> 8) & 3);\n");
2529 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2534 if (s
[1] == 'x') /* yx */
2536 printf (" int n = (iword & 0xc) ? \n");
2537 printf (" ((iword >> 8) & 1) + 6 : \n");
2538 printf (" REG_yx ((iword >> 8) & 3);\n");
2541 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2550 printf (" int m = (iword >> 4) & 0xf;\n");
2554 if (s
[1] == 'Y') /* XY */
2556 printf (" int m = (iword & 3) ? \n");
2557 printf (" ((iword >> 7) & 1) + 8 : \n");
2558 printf (" DSP_xy ((iword >> 6) & 3);\n");
2561 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2565 if (s
[1] == 'x') /* ax */
2567 printf (" int m = (iword & 3) ? \n");
2568 printf (" 7 - ((iword >> 6) & 2) : \n");
2569 printf (" DSP_ax ((iword >> 6) & 3);\n");
2572 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2576 if (s
[1] == 'X') /* YX */
2578 printf (" int m = (iword & 0xc) ? \n");
2579 printf (" ((iword >> 6) & 1) + 10 : \n");
2580 printf (" DSP_yx ((iword >> 6) & 3);\n");
2583 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2587 if (s
[1] == 'Y') /* AY */
2589 printf (" int m = (iword & 0xc) ? \n");
2590 printf (" 7 - ((iword >> 5) & 2) : \n");
2591 printf (" DSP_ay ((iword >> 6) & 3);\n");
2594 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2599 printf (" int i = (iword & 0x");
2634 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
2635 sextbit
- 1, sextbit
- 1);
2639 printf (" TB (m,n);\n");
2641 printf (" TL (m);\n");
2643 printf (" TL (n);\n");
2648 for (r
= p
->refs
; *r
; r
++)
2650 if (*r
== '0') printf (" CREF (0);\n");
2651 if (*r
== '8') printf (" CREF (8);\n");
2652 if (*r
== '9') printf (" CREF (9);\n");
2653 if (*r
== 'n') printf (" CREF (n);\n");
2654 if (*r
== 'm') printf (" CREF (m);\n");
2659 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2663 printf (" %s\n", p
->stuff
[j
]);
2671 for (r
= p
->defs
; *r
; r
++)
2673 if (*r
== '0') printf(" CDEF (0);\n");
2674 if (*r
== 'n') printf(" CDEF (n);\n");
2675 if (*r
== 'm') printf(" CDEF (m);\n");
2679 printf (" break;\n");
2688 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
2689 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
2690 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
2691 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
2692 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
2693 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
2694 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
2695 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
2696 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
2697 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
2698 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
2699 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
2700 printf (" switch (jump_table[iword]) {\n");
2702 gensim_caselist (tab
);
2703 gensim_caselist (movsxy_tab
);
2705 printf (" default:\n");
2707 printf (" RAISE_EXCEPTION (SIGILL);\n");
2718 for (p
= tab
; p
->name
; p
++)
2721 printf ("#define OPC_");
2735 printf (" %d\n",p
->index
);
2739 static int ppi_index
;
2741 /* Take a ppi code, expand all varying fields in it and fill all the
2742 right entries in 'table' with the opcode index.
2743 NOTE: tail recursion optimization removed for simplicity. */
2746 expand_ppi_code (val
, i
, s
)
2756 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n", s
[0]);
2761 /* The last four bits are disregarded for the switch table. */
2765 /* Four-bit expansion. */
2766 for (j
= 0; j
< 16; j
++)
2767 expand_ppi_code ((val
<< 4) + j
, i
, s
+ 4);
2771 expand_ppi_code ((val
<< 1), i
, s
+ 1);
2774 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
2779 expand_ppi_code ((val
<< 1), i
, s
+ 1);
2780 expand_ppi_code ((val
<< 1) + 1, i
, s
+ 1);
2783 expand_ppi_code ((val
<< 2) + 1, ppi_index
++, s
+ 2);
2784 expand_ppi_code ((val
<< 2) + 2, i
, s
+ 2);
2785 expand_ppi_code ((val
<< 2) + 3, i
, s
+ 2);
2796 for (p
= ppi_tab
; p
->name
; p
++)
2798 p
->index
= ppi_index
++;
2799 expand_ppi_code (0, p
->index
, p
->code
);
2808 printf ("#define DSR_MASK_G 0x80\n");
2809 printf ("#define DSR_MASK_Z 0x40\n");
2810 printf ("#define DSR_MASK_N 0x20\n");
2811 printf ("#define DSR_MASK_V 0x10\n");
2813 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2814 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2815 printf (" if (overflow && S) \\\n");
2817 printf (" if (res_grd & 0x80) \\\n");
2819 printf (" res = 0x80000000; \\\n");
2820 printf (" res_grd |= 0xff; \\\n");
2822 printf (" else \\\n");
2824 printf (" res = 0x7fffffff; \\\n");
2825 printf (" res_grd &= ~0xff; \\\n");
2827 printf (" overflow = 0; \\\n");
2829 printf ("} while (0)\n");
2831 printf ("#define ADD_SUB_GE \\\n");
2832 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2834 printf ("static void\n");
2835 printf ("ppi_insn (iword)\n");
2836 printf (" int iword;\n");
2838 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
2839 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2840 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
2841 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2842 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
2843 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2844 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
2845 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2846 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
2847 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2848 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
2849 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2851 printf (" int z;\n");
2852 printf (" int res, res_grd;\n");
2853 printf (" int carry, overflow, greater_equal;\n");
2855 printf (" switch (ppi_table[iword >> 4]) {\n");
2857 for (; p
->name
; p
++)
2865 printf (" /* %s %s */\n", p
->name
, p
->code
);
2866 printf (" case %d: \n", p
->index
);
2869 for (shift
= 16; *s
; )
2874 printf (" int i = (iword >> 4) & 0x7f;\n");
2884 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2890 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2891 printf ("\treturn;\n");
2893 printf (" case %d: \n", p
->index
+ 1);
2905 printf (" z = iword & 0xf;\n");
2913 else if (havedecl
== 2)
2915 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2920 (havedecl
== 2 ? " " : ""),
2928 printf (" if (iword & 0x200)\n");
2929 printf (" goto assign_z;\n");
2931 printf (" break;\n");
2935 printf (" default:\n");
2937 printf (" RAISE_EXCEPTION (SIGILL);\n");
2938 printf (" return;\n");
2941 printf (" DSR &= ~0xf1;\n");
2942 printf (" if (res || res_grd)\n");
2943 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2945 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2946 printf (" assign_dc:\n");
2947 printf (" switch (DSR >> 1 & 7)\n");
2949 printf (" case 0: /* Carry Mode */\n");
2950 printf (" DSR |= carry;\n");
2951 printf (" case 1: /* Negative Value Mode */\n");
2952 printf (" DSR |= res_grd >> 7 & 1;\n");
2953 printf (" case 2: /* Zero Value Mode */\n");
2954 printf (" DSR |= DSR >> 6 & 1;\n");
2955 printf (" case 3: /* Overflow mode\n");
2956 printf (" DSR |= overflow >> 4;\n");
2957 printf (" case 4: /* Signed Greater Than Mode */\n");
2958 printf (" DSR |= DSR >> 7 & 1;\n");
2959 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2960 printf (" DSR |= greater_equal >> 7;\n");
2962 printf (" assign_z:\n");
2963 printf (" if (0xa05f >> z & 1)\n");
2965 printf (" RAISE_EXCEPTION (SIGILL);\n");
2966 printf (" return;\n");
2968 printf (" DSP_R (z) = res;\n");
2969 printf (" DSP_GRD (z) = res_grd;\n");
2978 /* verify the table before anything else */
2981 for (p
= tab
; p
->name
; p
++)
2983 /* check that the code field contains 16 bits */
2984 if (strlen (p
->code
) != 16)
2986 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2987 p
->code
, strlen (p
->code
), p
->name
);
2993 /* now generate the requested data */
2996 if (strcmp (av
[1], "-t") == 0)
3000 else if (strcmp (av
[1], "-d") == 0)
3004 else if (strcmp (av
[1], "-s") == 0)
3007 dumptable ("sh_jump_table", 1 << 16, 0);
3009 memset (table
, 0, sizeof table
);
3010 filltable (movsxy_tab
);
3011 expand_ppi_movxy ();
3012 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3014 memset (table
, 0, sizeof table
);
3016 dumptable ("ppi_table", 1 << 12, 0);
3018 else if (strcmp (av
[1], "-x") == 0)
3021 filltable (movsxy_tab
);
3024 else if (strcmp (av
[1], "-p") == 0)
3031 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.093653 seconds and 4 git commands to generate.