1 /* Simulator/Opcode generator for the Hitachi Super-H architecture.
3 Written by Steve Chamberlain of Cygnus Support.
6 This file is part of SH sim
9 THIS SOFTWARE IS NOT COPYRIGHTED
11 Cygnus offers the following for use in the public domain. Cygnus
12 makes no warranty with regard to the software or it's performance
13 and the user accepts the software "AS IS" with all faults.
15 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 /* This program generates the opcode table for the assembler and
24 -t prints a pretty table for the assembler manual
25 -s generates the simulator code jump table
26 -d generates a define table
27 -x generates the simulator code switch statement
28 default used to generate the opcode tables
34 #define MAX_NR_STUFF 42
42 char *stuff
[MAX_NR_STUFF
];
50 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
53 " UNDEF(n); /* see #ifdef PARANOID */",
57 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
61 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
63 "SET_SR_T (ult < R[n]);",
65 "SET_SR_T (T || (R[n] < ult));",
68 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
70 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
74 { "0", "", "and #<imm>,R0", "11001001i8*1....",
77 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
80 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
82 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
85 { "", "", "bf <bdisp8>", "10001011i8p1....",
87 " SET_NIP (PC + 4 + (SEXT(i) * 2));",
92 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
94 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
96 " Delay_Slot (PC + 2);",
100 { "", "", "bra <bdisp12>", "1010i12.........",
101 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
103 "Delay_Slot (PC + 2);",
106 { "", "n", "braf <REG_N>", "0000nnnn00100011",
107 "SET_NIP (PC + 4 + R[n]);",
109 "Delay_Slot (PC + 2);",
112 { "", "", "bsr <bdisp12>", "1011i12.........",
113 "PR = PH2T (PC + 4);",
114 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
116 "Delay_Slot (PC + 2);",
119 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
120 "PR = PH2T (PC) + 4;",
121 "SET_NIP (PC + 4 + R[n]);",
123 "Delay_Slot (PC + 2);",
126 { "", "", "bt <bdisp8>", "10001001i8p1....",
128 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
133 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
135 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
137 " Delay_Slot (PC + 2);",
141 { "", "", "clrmac", "0000000000101000",
146 { "", "", "clrs", "0000000001001000",
150 { "", "", "clrt", "0000000000001000",
154 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
155 "SET_SR_T (R0 == SEXT (i));",
157 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
158 "SET_SR_T (R[n] == R[m]);",
160 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
161 "SET_SR_T (R[n] >= R[m]);",
163 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
164 "SET_SR_T (R[n] > R[m]);",
166 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
167 "SET_SR_T (UR[n] > UR[m]);",
169 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
170 "SET_SR_T (UR[n] >= UR[m]);",
172 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
173 "SET_SR_T (R[n] > 0);",
175 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
176 "SET_SR_T (R[n] >= 0);",
178 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
179 "ult = R[n] ^ R[m];",
180 "SET_SR_T (((ult & 0xff000000) == 0)",
181 " | ((ult & 0xff0000) == 0)",
182 " | ((ult & 0xff00) == 0)",
183 " | ((ult & 0xff) == 0));",
186 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
187 "SET_SR_Q ((R[n] & sbit) != 0);",
188 "SET_SR_M ((R[m] & sbit) != 0);",
189 "SET_SR_T (M != Q);",
192 { "", "", "div0u", "0000000000011001",
198 { "", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", /* ? MVS */
199 "div1 (R, m, n/*, T*/);",
202 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
203 "dmul (1/*signed*/, R[n], R[m]);",
206 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
207 "dmul (0/*unsigned*/, R[n], R[m]);",
210 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
212 "SET_SR_T (R[n] == 0);",
215 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
216 "R[n] = SEXT (R[m]);",
218 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
219 "R[n] = SEXTW (R[m]);",
222 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
223 "R[n] = (R[m] & 0xff);",
225 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
226 "R[n] = (R[m] & 0xffff);",
230 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
231 "FP_UNARY (n, fabs);",
232 "/* FIXME: FR(n) &= 0x7fffffff; */",
236 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
241 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
242 "FP_CMP (n, ==, m);",
245 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
250 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
251 "if (! FPSCR_PR || n & 1)",
252 " RAISE_EXCEPTION (SIGILL);",
266 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
267 "if (! FPSCR_PR || n & 1)",
268 " RAISE_EXCEPTION (SIGILL);",
282 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
284 "/* FIXME: check for DP and (n & 1) == 0? */",
288 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
289 "/* FIXME: not implemented */",
290 "RAISE_EXCEPTION (SIGILL);",
291 "/* FIXME: check for DP and (n & 1) == 0? */",
295 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
296 "SET_FR (n, (float)0.0);",
297 "/* FIXME: check for DP and (n & 1) == 0? */",
301 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
302 "SET_FR (n, (float)1.0);",
303 "/* FIXME: check for DP and (n & 1) == 0? */",
307 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
318 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
321 " SET_DR (n, (double)FPUL);",
324 " SET_FR (n, (float)FPUL);",
329 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
330 "SET_FR (n, FR(m) * FR(0) + FR(n));",
331 "/* FIXME: check for DP and (n & 1) == 0? */",
335 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
338 " int ni = XD_TO_XF (n);",
339 " int mi = XD_TO_XF (m);",
340 " SET_XF (ni + 0, XF (mi + 0));",
341 " SET_XF (ni + 1, XF (mi + 1));",
345 " SET_FR (n, FR (m));",
349 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
358 " WLAT (R[n], FI(m));",
362 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
371 " SET_FI(n, RLAT(R[m]));",
375 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
385 " SET_FI (n, RLAT (R[m]));",
390 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
401 " WLAT (R[n], FI(m));",
405 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
409 " RDAT (R[0]+R[m], n);",
414 " SET_FI(n, RLAT(R[0] + R[m]));",
418 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
422 " WDAT (R[0]+R[n], m);",
427 " WLAT((R[0]+R[n]), FI(m));",
431 /* sh4: See fmov instructions above for move to/from extended fp registers */
434 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
439 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
444 { "", "", "frchg", "1111101111111101",
446 " RAISE_EXCEPTION (SIGILL);",
448 " SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
452 { "", "", "fschg", "1111001111111101",
453 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
457 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
458 "FP_UNARY(n, sqrt);",
462 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
467 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
470 " if (DR(n) != DR(n)) /* NaN */",
471 " FPUL = 0x80000000;",
473 " FPUL = (int)DR(n);",
476 "if (FR(n) != FR(n)) /* NaN */",
477 " FPUL = 0x80000000;",
479 " FPUL = (int)FR(n);",
483 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
493 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
494 "SET_NIP (PT2H (R[n]));",
496 "Delay_Slot (PC + 2);",
499 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
500 "PR = PH2T (PC + 4);",
502 " gotcall (PR, R[n]);",
503 "SET_NIP (PT2H (R[n]));",
505 "Delay_Slot (PC + 2);",
508 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
510 "/* FIXME: user mode */",
512 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
514 "/* FIXME: user mode */",
516 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
520 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
522 "/* FIXME: user mode */",
525 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
527 "CREG (m) = RLAT (R[n]);",
529 "/* FIXME: user mode */",
531 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
533 "SET_SR (RLAT (R[n]));",
535 "/* FIXME: user mode */",
537 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
539 "SET_MOD (RLAT (R[n]));",
543 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
545 "DBR = RLAT (R[n]);",
547 "/* FIXME: user mode */",
552 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
553 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
555 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
556 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
559 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
562 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
564 "SREG (m) = RLAT(R[n]);",
567 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
568 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
571 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
572 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
574 "SET_FPSCR (RLAT(R[n]));",
578 { "", "", "ldtlb", "0000000000111000",
579 "/* We don't implement cache or tlb, so this is a noop. */",
582 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
583 "macl(&R0,memory,n,m);",
586 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
587 "macw(&R0,memory,n,m,endianw);",
590 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
593 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
597 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
599 "R0 = RSBAT (i + GBR);",
602 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
604 "R0 = RSBAT (i + R[m]);",
607 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
609 "R[n] = RSBAT (R0 + R[m]);",
612 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
614 "R[n] = RSBAT (R[m]);",
618 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
620 "WBAT (R[n], R[m]);",
622 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
624 "WBAT (i + GBR, R0);",
626 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
628 "WBAT (i + R[m], R0);",
630 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
632 "WBAT (R[n] + R0, R[m]);",
634 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
637 "WBAT (R[n], R[m]);",
639 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
641 "R[n] = RSBAT (R[m]);",
645 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
647 "R0 = RLAT (i + GBR);",
650 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
652 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
655 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
657 "R[n] = RLAT (i + R[m]);",
660 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
662 "R[n] = RLAT (R0 + R[m]);",
665 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
667 "R[n] = RLAT (R[m]);",
671 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
673 "R[n] = RLAT (R[m]);",
676 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
678 "WLAT (i + GBR, R0);",
680 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
682 "WLAT (i + R[n], R[m]);",
684 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
686 "WLAT (R0 + R[n], R[m]);",
688 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
691 "WLAT (R[n], R[m]);",
693 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
695 "WLAT (R[n], R[m]);",
698 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
700 "R0 = RSWAT (i + GBR);",
703 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
705 "R[n] = RSWAT (PH2T (PC + 4 + i));",
708 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
710 "R0 = RSWAT (i + R[m]);",
713 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
715 "R[n] = RSWAT (R0 + R[m]);",
718 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
720 "R[n] = RSWAT (R[m]);",
724 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
726 "R[n] = RSWAT (R[m]);",
729 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
731 "WWAT (i + GBR, R0);",
733 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
735 "WWAT (i + R[m], R0);",
737 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
739 "WWAT (R0 + R[n], R[m]);",
741 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
744 "WWAT (R[n], R[m]);",
746 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
748 "WWAT (R[n], R[m]);",
751 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
752 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
755 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
756 "/* We don't simulate cache, so this insn is identical to mov. */",
758 "WLAT (R[n], R[0]);",
761 { "n", "", "movt <REG_N>", "0000nnnn00101001",
765 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
766 "MACL = ((int)R[n]) * ((int)R[m]);",
769 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
770 "MACL = R[n] * R[m];",
774 /* muls.w - see muls */
775 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
776 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
779 /* mulu.w - see mulu */
780 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
781 "MACL = (((unsigned int)(unsigned short)R[n])",
782 " * ((unsigned int)(unsigned short)R[m]));",
785 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
789 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
791 "SET_SR_T (ult > 0);",
792 "R[n] = ult - R[m];",
793 "SET_SR_T (T || (R[n] > ult));",
796 { "", "", "nop", "0000000000001001",
800 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
804 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
805 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
806 "/* FIXME: Cache not implemented */",
809 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
810 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
811 "/* FIXME: Cache not implemented */",
814 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
815 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
816 "/* FIXME: Cache not implemented */",
819 { "0", "", "or #<imm>,R0", "11001011i8*1....",
822 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
825 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
827 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
830 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
831 "/* Except for the effect on the cache - which is not simulated -",
832 " this is like a nop. */",
835 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
837 "R[n] = (R[n] << 1) | T;",
841 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
843 "R[n] = (UR[n] >> 1) | (T << 31);",
847 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
848 "SET_SR_T (R[n] < 0);",
853 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
854 "SET_SR_T (R[n] & 1);",
855 "R[n] = UR[n] >> 1;",
856 "R[n] |= (T << 31);",
859 { "", "", "rte", "0000000000101011",
863 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
865 "SET_SR (RLAT (R[15]) & 0x3f3);",
867 "Delay_Slot (PC + 2);",
870 "SET_NIP (PT2H (SPC));",
872 "Delay_Slot (PC + 2);",
876 { "", "", "rts", "0000000000001011",
877 "SET_NIP (PT2H (PR));",
879 "Delay_Slot (PC + 2);",
883 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
886 { "", "", "setrc #<imm>", "10000010i8*1....",
887 /* It would be more realistic to let loop_start point to some static
888 memory that contains an illegal opcode and then give a bus error when
889 the loop is eventually encountered, but it seems not only simpler,
890 but also more debugging-friendly to just catch the failure here. */
891 "if (BUSERROR (RS | RE, maskw))",
892 " RAISE_EXCEPTION (SIGILL);",
895 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
896 " CHECK_INSN_PTR (insn_ptr);",
900 { "", "", "sets", "0000000001011000",
904 { "", "", "sett", "0000000000011000",
908 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
909 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
912 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
913 "SET_SR_T (R[n] < 0);",
917 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
918 "SET_SR_T (R[n] & 1);",
922 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
923 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
926 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
927 "SET_SR_T (R[n] < 0);",
931 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
934 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
937 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
941 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
942 "SET_SR_T (R[n] & 1);",
943 "R[n] = UR[n] >> 1;",
946 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
947 "R[n] = UR[n] >> 2;",
949 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
950 "R[n] = UR[n] >> 8;",
952 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
953 "R[n] = UR[n] >> 16;",
956 { "", "", "sleep", "0000000000011011",
957 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
960 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
965 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
968 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
972 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
975 "WLAT (R[n], CREG (m));",
978 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
983 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
990 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
993 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
996 "WLAT (R[n], SREG (m));",
999 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1003 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1005 "SET_SR_T (ult > R[n]);",
1006 "R[n] = ult - R[m];",
1007 "SET_SR_T (T || (R[n] > ult));",
1010 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1011 "ult = R[n] - R[m];",
1012 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1016 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1017 "R[n] = ((R[m] & 0xffff0000)",
1018 " | ((R[m] << 8) & 0xff00)",
1019 " | ((R[m] >> 8) & 0x00ff));",
1021 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1022 "R[n] = (((R[m] << 16) & 0xffff0000)",
1023 " | ((R[m] >> 16) & 0x00ffff));",
1026 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1028 "ult = RBAT(R[n]);",
1029 "SET_SR_T (ult == 0);",
1030 "WBAT(R[n],ult|0x80);",
1033 { "0", "", "trapa #<imm>", "11000011i8*1....",
1034 "long imm = 0xff & i;",
1035 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1036 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1041 " WLAT (R[15], GET_SR());",
1043 " WLAT (R[15], PH2T (PC + 2));",
1045 "else if (!SR_BL) {",
1047 " SPC = PH2T (PC + 2);",
1048 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1049 " /* FIXME: EXPEVT = 0x00000160; */",
1051 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1055 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1056 "SET_SR_T ((R[n] & R[m]) == 0);",
1058 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1059 "SET_SR_T ((R0 & i) == 0);",
1061 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1063 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1066 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1069 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1072 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1074 "ult = RBAT (GBR+R0);",
1076 "WBAT (GBR + R0, ult);",
1079 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1080 "R[n] = (((R[n] >> 16) & 0xffff)",
1081 " | ((R[m] << 16) & 0xffff0000));",
1085 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1086 "divl(0,R[n],R[m]);",
1088 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1089 "divl(0,R[n],R[m]);",
1097 /* If this is disabled, the simulator speeds up by about 12% on a
1098 450 MHz PIII - 9% with ACE_FAST.
1099 Maybe we should have separate simulator loops? */
1101 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1104 "DSP_R (m) = RSWAT (R[n]) << 16;",
1105 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1107 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1109 "DSP_R (m) = RSWAT (R[n]) << 16;",
1110 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1112 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1114 "DSP_R (m) = RSWAT (R[n]) << 16;",
1115 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1118 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1120 "DSP_R (m) = RSWAT (R[n]) << 16;",
1121 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1124 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1127 "DSP_R (m) = RSWAT (R[n]);",
1129 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1131 "DSP_R (m) = RSWAT (R[n]);",
1133 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1135 "DSP_R (m) = RSWAT (R[n]);",
1138 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1140 "DSP_R (m) = RSWAT (R[n]);",
1143 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1146 "WWAT (R[n], DSP_R (m) >> 16);",
1148 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1150 "WWAT (R[n], DSP_R (m) >> 16);",
1152 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1154 "WWAT (R[n], DSP_R (m) >> 16);",
1157 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1159 "WWAT (R[n], DSP_R (m) >> 16);",
1162 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1165 "WWAT (R[n], SEXT (DSP_R (m)));",
1167 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1169 "WWAT (R[n], SEXT (DSP_R (m)));",
1171 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1173 "WWAT (R[n], SEXT (DSP_R (m)));",
1176 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1178 "WWAT (R[n], SEXT (DSP_R (m)));",
1181 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1184 "DSP_R (m) = RLAT (R[n]);",
1185 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1187 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1189 "DSP_R (m) = RLAT (R[n]);",
1190 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1192 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1194 "DSP_R (m) = RLAT (R[n]);",
1195 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1198 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1200 "DSP_R (m) = RLAT (R[n]);",
1201 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1204 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1207 "WLAT (R[n], DSP_R (m));",
1209 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1211 "WLAT (R[n], DSP_R (m));",
1213 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1215 "WLAT (R[n], DSP_R (m));",
1218 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1220 "WLAT (R[n], DSP_R (m));",
1223 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1226 "WLAT (R[n], SEXT (DSP_R (m)));",
1228 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1230 "WLAT (R[n], SEXT (DSP_R (m)));",
1232 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1234 "WLAT (R[n], SEXT (DSP_R (m)));",
1237 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1239 "WLAT (R[n], SEXT (DSP_R (m)));",
1242 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1243 "DSP_R (m) = RSWAT (R[n]) << 16;",
1244 "iword &= 0xfd53; goto top;",
1246 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1247 "DSP_R (m) = RSWAT (R[n]) << 16;",
1248 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1249 "iword &= 0xfd53; goto top;",
1251 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001100",
1252 "DSP_R (m) = RSWAT (R[n]) << 16;",
1253 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1254 "iword &= 0xfd53; goto top;",
1256 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1257 "WWAT (R[n], DSP_R (m) >> 16);",
1258 "iword &= 0xfd53; goto top;",
1260 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1261 "WWAT (R[n], DSP_R (m) >> 16);",
1262 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1263 "iword &= 0xfd53; goto top;",
1265 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
1266 "WWAT (R[n], DSP_R (m) >> 16);",
1267 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1268 "iword &= 0xfd53; goto top;",
1270 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1271 "DSP_R (m) = RSWAT (R[n]) << 16;",
1273 { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
1274 "DSP_R (m) = RSWAT (R[n]) << 16;",
1275 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1277 { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000011",
1278 "DSP_R (m) = RSWAT (R[n]) << 16;",
1279 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1281 { "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
1282 "WWAT (R[n], DSP_R (m) >> 16);",
1284 { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
1285 "WWAT (R[n], DSP_R (m) >> 16);",
1286 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1288 { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010011",
1289 "WWAT (R[n], DSP_R (m) >> 16);",
1290 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1292 { "", "", "nopx nopy", "1111000000000000",
1295 { "", "", "ppi", "1111100000000000",
1296 "ppi_insn (RIAT (nip));",
1298 "iword &= 0xf7ff; goto top;",
1305 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1306 "int Sz = DSP_R (z) & 0xffff0000;",
1310 "else if (i >= 128 - 16)",
1311 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1314 " RAISE_EXCEPTION (SIGILL);",
1317 "res &= 0xffff0000;",
1321 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1322 "int Sz = DSP_R (z);",
1323 "int Sz_grd = GET_DSP_GRD (z);",
1335 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1337 " res_grd = SEXT (res_grd);",
1338 " carry = res_grd & 1;",
1340 "else if (i >= 96)",
1345 " res_grd = SIGN32 (Sz_grd);",
1350 " res = Sz >> i | Sz_grd << 32 - i;",
1351 " res_grd = Sz_grd >> i;",
1353 " carry = Sz >> (i - 1) & 1;",
1357 " RAISE_EXCEPTION (SIGILL);",
1360 "COMPUTE_OVERFLOW;",
1361 "greater_equal = 0;",
1363 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1364 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1365 "if (res == 0x80000000)",
1366 " res = 0x7fffffff;",
1368 "DSP_GRD (g) = SIGN32 (res);",
1371 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1372 "int Sx = DSP_R (x);",
1373 "int Sx_grd = GET_DSP_GRD (x);",
1374 "int Sy = DSP_R (y);",
1375 "int Sy_grd = SIGN32 (Sy);",
1377 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1378 "if (res == 0x80000000)",
1379 " res = 0x7fffffff;",
1381 "DSP_GRD (g) = SIGN32 (res);",
1385 "carry = (unsigned) res > (unsigned) Sx;",
1386 "res_grd = Sx_grd - Sy_grd - carry;",
1387 "COMPUTE_OVERFLOW;",
1390 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1391 "int Sx = DSP_R (x);",
1392 "int Sx_grd = GET_DSP_GRD (x);",
1393 "int Sy = DSP_R (y);",
1394 "int Sy_grd = SIGN32 (Sy);",
1396 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1397 "if (res == 0x80000000)",
1398 " res = 0x7fffffff;",
1400 "DSP_GRD (g) = SIGN32 (res);",
1404 "carry = (unsigned) res < (unsigned) Sx;",
1405 "res_grd = Sx_grd + Sy_grd + carry;",
1406 "COMPUTE_OVERFLOW;",
1408 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1409 "int Sx = DSP_R (x);",
1410 "int Sx_grd = GET_DSP_GRD (x);",
1411 "int Sy = DSP_R (y);",
1412 "int Sy_grd = SIGN32 (Sy);",
1414 "res = Sx - Sy - (DSR & 1);",
1415 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1416 "res_grd = Sx_grd + Sy_grd + carry;",
1417 "COMPUTE_OVERFLOW;",
1420 "if (res || res_grd)\n",
1421 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1423 " DSR |= DSR_MASK_Z | overflow;\n",
1427 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1428 "int Sx = DSP_R (x);",
1429 "int Sx_grd = GET_DSP_GRD (x);",
1430 "int Sy = DSP_R (y);",
1431 "int Sy_grd = SIGN32 (Sy);",
1433 "res = Sx + Sy + (DSR & 1);",
1434 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1435 "res_grd = Sx_grd + Sy_grd + carry;",
1436 "COMPUTE_OVERFLOW;",
1439 "if (res || res_grd)\n",
1440 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1442 " DSR |= DSR_MASK_Z | overflow;\n",
1446 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1447 "int Sx = DSP_R (x);",
1448 "int Sx_grd = GET_DSP_GRD (x);",
1449 "int Sy = DSP_R (y);",
1450 "int Sy_grd = SIGN32 (Sy);",
1452 "z = 17; /* Ignore result. */",
1454 "carry = (unsigned) res > (unsigned) Sx;",
1455 "res_grd = Sx_grd - Sy_grd - carry;",
1456 "COMPUTE_OVERFLOW;",
1459 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1461 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1463 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1465 "res_grd = GET_DSP_GRD (x);",
1471 " carry = (res != 0); /* The manual has a bug here. */",
1472 " res_grd = -res_grd - carry;",
1474 "COMPUTE_OVERFLOW;",
1475 "/* ??? The re-computing of overflow after",
1476 " saturation processing is specific to pabs. */",
1477 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1480 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1481 "int Sx = DSP_R (x);",
1482 "int Sx_grd = GET_DSP_GRD (x);",
1484 "res = (Sx + 0x8000) & 0xffff0000;",
1485 "carry = (unsigned) res < (unsigned) Sx;",
1486 "res_grd = Sx_grd + carry;",
1487 "COMPUTE_OVERFLOW;",
1490 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1494 "greater_equal = DSR_MASK_G;",
1504 " res = 0x7fffffff;",
1507 " overflow = DSR_MASK_V;",
1508 " greater_equal = 0;",
1513 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1514 "int Sy = DSP_R (y);",
1515 "int Sy_grd = SIGN32 (Sy);",
1517 "res = (Sy + 0x8000) & 0xffff0000;",
1518 "carry = (unsigned) res < (unsigned) Sy;",
1519 "res_grd = Sy_grd + carry;",
1520 "COMPUTE_OVERFLOW;",
1523 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1524 "int Sx = DSP_R (x) & 0xffff0000;",
1525 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1529 "else if (Sy >= 128 - 16)",
1530 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
1533 " RAISE_EXCEPTION (SIGILL);",
1536 "goto cond_logical;",
1538 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1539 "int Sx = DSP_R (x);",
1540 "int Sx_grd = GET_DSP_GRD (x);",
1541 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1553 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1555 " res_grd = SEXT (res_grd);",
1556 " carry = res_grd & 1;",
1558 "else if (Sy >= 96)",
1563 " res_grd = SIGN32 (Sx_grd);",
1568 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1569 " res_grd = Sx_grd >> Sy;",
1571 " carry = Sx >> (Sy - 1) & 1;",
1575 " RAISE_EXCEPTION (SIGILL);",
1578 "COMPUTE_OVERFLOW;",
1579 "greater_equal = 0;",
1581 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1582 "int Sx = DSP_R (x);",
1583 "int Sx_grd = GET_DSP_GRD (x);",
1584 "int Sy = DSP_R (y);",
1585 "int Sy_grd = SIGN32 (Sy);",
1588 "carry = (unsigned) res > (unsigned) Sx;",
1589 "res_grd = Sx_grd - Sy_grd - carry;",
1590 "COMPUTE_OVERFLOW;",
1593 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
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);",
1600 "carry = (unsigned) res < (unsigned) Sx;",
1601 "res_grd = Sx_grd + Sy_grd + carry;",
1602 "COMPUTE_OVERFLOW;",
1605 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1606 "res = DSP_R (x) & DSP_R (y);",
1608 "res &= 0xffff0000;",
1610 "if (iword & 0x200)\n",
1611 " goto assign_z;\n",
1615 "greater_equal = 0;",
1618 " DSR |= res >> 26 & DSR_MASK_N;\n",
1620 " DSR |= DSR_MASK_Z;\n",
1621 "goto assign_dc;\n",
1623 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1624 "res = DSP_R (x) ^ DSP_R (y);",
1625 "goto cond_logical;",
1627 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1628 "res = DSP_R (x) | DSP_R (y);",
1629 "goto cond_logical;",
1631 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1632 "int Sx = DSP_R (x);",
1633 "int Sx_grd = GET_DSP_GRD (x);",
1635 "res = Sx - 0x10000;",
1636 "carry = res > Sx;",
1637 "res_grd = Sx_grd - carry;",
1638 "COMPUTE_OVERFLOW;",
1640 "res &= 0xffff0000;",
1642 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1643 "int Sx = DSP_R (x);",
1644 "int Sx_grd = GET_DSP_GRD (x);",
1646 "res = Sx + 0x10000;",
1647 "carry = res < Sx;",
1648 "res_grd = Sx_grd + carry;",
1649 "COMPUTE_OVERFLOW;",
1651 "res &= 0xffff0000;",
1653 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1654 "int Sy = DSP_R (y);",
1655 "int Sy_grd = SIGN32 (Sy);",
1657 "res = Sy - 0x10000;",
1658 "carry = res > Sy;",
1659 "res_grd = Sy_grd - carry;",
1660 "COMPUTE_OVERFLOW;",
1662 "res &= 0xffff0000;",
1664 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1665 "int Sy = DSP_R (y);",
1666 "int Sy_grd = SIGN32 (Sy);",
1668 "res = Sy + 0x10000;",
1669 "carry = res < Sy;",
1670 "res_grd = Sy_grd + carry;",
1671 "COMPUTE_OVERFLOW;",
1673 "res &= 0xffff0000;",
1675 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1680 "greater_equal = 1;",
1682 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1683 "unsigned Sx = DSP_R (x);",
1684 "int Sx_grd = GET_DSP_GRD (x);",
1689 " Sx_grd = ~Sx_grd;",
1703 " if (Sx & ~0 << i)",
1711 "res_grd = SIGN32 (res);",
1716 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1717 "unsigned Sy = DSP_R (y);",
1726 " if (Sy & ~0 << i)",
1734 "res_grd = SIGN32 (res);",
1739 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1740 "int Sx = DSP_R (x);",
1741 "int Sx_grd = GET_DSP_GRD (x);",
1744 "carry = res != 0;",
1745 "res_grd = 0 - Sx_grd - carry;",
1746 "COMPUTE_OVERFLOW;",
1749 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1751 "res_grd = GET_DSP_GRD (x);",
1753 "COMPUTE_OVERFLOW;",
1756 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1757 "int Sy = DSP_R (y);",
1758 "int Sy_grd = SIGN32 (Sy);",
1761 "carry = res != 0;",
1762 "res_grd = 0 - Sy_grd - carry;",
1763 "COMPUTE_OVERFLOW;",
1766 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1768 "res_grd = SIGN32 (res);",
1770 "COMPUTE_OVERFLOW;",
1773 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1775 "res_grd = SIGN32 (res);",
1778 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1780 "res_grd = SIGN32 (res);",
1783 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1784 "if (0xa05f >> z & 1)",
1785 " RAISE_EXCEPTION (SIGILL);",
1787 " MACH = DSP_R (z);",
1790 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1791 "if (0xa05f >> z & 1)",
1792 " RAISE_EXCEPTION (SIGILL);",
1794 " MACL = DSP_R (z) = res;",
1800 /* Tables of things to put into enums for sh-opc.h */
1801 static char *nibble_type_list
[] =
1836 char *arg_type_list
[] =
1870 make_enum_list (name
, s
)
1875 printf ("typedef enum {\n");
1878 printf ("\t%s,\n", *s
);
1882 printf ("} %s;\n", name
);
1894 memcpy (bufa
, a
->code
, 4);
1895 memcpy (bufa
+ 4, a
->code
+ 12, 4);
1898 memcpy (bufb
, b
->code
, 4);
1899 memcpy (bufb
+ 4, b
->code
+ 12, 4);
1901 diff
= strcmp (bufa
, bufb
);
1902 /* Stabilize the sort, so that later entries can override more general
1903 preceding entries. */
1904 return diff
? diff
: a
- b
;
1918 qsort (tab
, len
, sizeof (*p
), qfunc
);
1926 for (p
= tab
; p
->name
; p
++)
1928 printf ("%s %-30s\n", p
->code
, p
->name
);
1934 /* Convert a string of 4 binary digits into an int */
1954 static unsigned char table
[1 << 16];
1956 /* Take an opcode expand all varying fields in it out and fill all the
1957 right entries in 'table' with the opcode index*/
1960 expand_opcode (shift
, val
, i
, s
)
1982 val
|= bton (s
) << shift
;
1983 if (s
[2] == '0' || s
[2] == '1')
1984 expand_opcode (shift
- 4, val
, i
, s
+ 4);
1985 else if (s
[2] == 'N')
1986 for (j
= 0; j
< 4; j
++)
1987 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
1988 else if (s
[2] == 'x')
1989 for (j
= 0; j
< 4; j
+= 2)
1990 for (m
= 0; m
< 32; m
++)
1992 /* Ignore illegal nopy */
1993 if ((m
& 7) == 0 && m
!= 0)
1995 mv
= m
& 3 | (m
& 4) << 2 | (m
& 8) << 3 | (m
& 16) << 4;
1996 expand_opcode (shift
- 4, val
| mv
| (j
<< shift
), i
,
1999 else if (s
[2] == 'y')
2000 for (j
= 0; j
< 2; j
++)
2001 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2006 for (j
= 0; j
< 16; j
++)
2008 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2013 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2014 for (j
= 5; j
< 16; j
++)
2016 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2020 for (j
= 13; j
<= 15; j
+=2)
2021 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2024 /* System registers mach, macl, pr: */
2025 for (j
= 0; j
< 3; j
++)
2026 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2027 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2028 for (j
= 5; j
< 12; j
++)
2029 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2033 val
|= bton (s
) << shift
;
2034 for (j
= 0; j
< 16; j
+= 8)
2035 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2039 val
|= bton (s
) << shift
;
2040 for (j
= 0; j
< 8; j
+= 4)
2041 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2045 for (j
= 0; j
< (1 << (shift
+ 4)); j
++)
2053 /* Print the jump table used to index an opcode into a switch
2057 dumptable (name
, size
, start
)
2067 printf ("unsigned char %s[%d]={\n", name
, size
);
2068 while (i
< start
+ size
)
2072 printf ("/* 0x%x */\n", i
);
2079 printf ("%2d", table
[i
+ j
+ k
]);
2098 static int index
= 1;
2101 for (; p
->name
; p
++)
2104 expand_opcode (12, 0, p
->index
, p
->code
);
2108 /* Table already contains all the switch case tags for 16-bit opcode double
2109 data transfer (ddt) insns, and the switch case tag for processing parallel
2110 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2111 latter tag to represent all combinations of ppi with ddt. */
2117 for (i
= 0xf000; i
< 0xf400; i
++)
2119 table
[i
+ 0x800] = table
[0xf800];
2126 for (; p
->name
; p
++)
2135 printf (" /* %s %s */\n", p
->name
, p
->code
);
2136 printf (" case %d: \n", p
->index
);
2144 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2156 printf (" int n = (iword >>8) & 0xf;\n");
2161 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2165 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2170 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2179 printf (" int m = (iword >>4) & 0xf;\n");
2183 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2187 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2191 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2195 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2200 printf (" int i = (iword & 0x");
2235 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2236 sextbit
- 1, sextbit
- 1);
2240 printf (" TB(m,n);\n");
2242 printf (" TL(m);\n");
2244 printf (" TL(n);\n");
2249 for (r
= p
->refs
; *r
; r
++)
2251 if (*r
== '0') printf(" CREF(0);\n");
2252 if (*r
== '8') printf(" CREF(8);\n");
2253 if (*r
== '9') printf(" CREF(9);\n");
2254 if (*r
== 'n') printf(" CREF(n);\n");
2255 if (*r
== 'm') printf(" CREF(m);\n");
2260 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2264 printf (" %s\n", p
->stuff
[j
]);
2272 for (r
= p
->defs
; *r
; r
++)
2274 if (*r
== '0') printf(" CDEF(0);\n");
2275 if (*r
== 'n') printf(" CDEF(n);\n");
2276 if (*r
== 'm') printf(" CDEF(m);\n");
2280 printf (" break;\n");
2289 printf (" switch (jump_table[iword]) {\n");
2291 gensim_caselist (tab
);
2292 gensim_caselist (movsxy_tab
);
2294 printf (" default:\n");
2296 printf (" RAISE_EXCEPTION (SIGILL);\n");
2307 for (p
= tab
; p
->name
; p
++)
2310 printf ("#define OPC_");
2314 if (isalpha(*s
)) printf("%c", *s
);
2315 if (*s
== ' ') printf("_");
2316 if (*s
== '@') printf("ind_");
2317 if (*s
== ',') printf("_");
2320 printf(" %d\n",p
->index
);
2324 static int ppi_index
;
2326 /* Take a ppi code, expand all varying fields in it and fill all the
2327 right entries in 'table' with the opcode index. */
2330 expand_ppi_code (val
, i
, s
)
2342 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n",
2346 /* The last eight bits are disregarded for the switch table. */
2364 expand_ppi_code (val
, i
, s
);
2371 expand_ppi_code (val
, ppi_index
++, s
);
2373 expand_ppi_code (val
, i
, s
);
2386 for (p
= ppi_tab
; p
->name
; p
++)
2388 p
->index
= ppi_index
++;
2389 expand_ppi_code (0, p
->index
, p
->code
);
2398 printf ("#define DSR_MASK_G 0x80\n");
2399 printf ("#define DSR_MASK_Z 0x40\n");
2400 printf ("#define DSR_MASK_N 0x20\n");
2401 printf ("#define DSR_MASK_V 0x10\n");
2403 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2404 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2405 printf (" if (overflow && S) \\\n");
2407 printf (" if (res_grd & 0x80) \\\n");
2409 printf (" res = 0x80000000; \\\n");
2410 printf (" res_grd |= 0xff; \\\n");
2412 printf (" else \\\n");
2414 printf (" res = 0x7fffffff; \\\n");
2415 printf (" res_grd &= ~0xff; \\\n");
2417 printf (" overflow = 0; \\\n");
2419 printf ("} while (0)\n");
2421 printf ("#define ADD_SUB_GE \\\n");
2422 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2424 printf ("static void\n");
2425 printf ("ppi_insn (iword)\n");
2426 printf (" int iword;\n");
2428 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2429 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2430 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2431 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2432 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2433 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2435 printf (" int z;\n");
2436 printf (" int res, res_grd;\n");
2437 printf (" int carry, overflow, greater_equal;\n");
2439 printf (" switch (ppi_table[iword >> 8]) {\n");
2441 for (; p
->name
; p
++)
2449 printf (" /* %s %s */\n", p
->name
, p
->code
);
2450 printf (" case %d: \n", p
->index
);
2453 for (shift
= 16; *s
; )
2458 printf (" int i = (iword >> 4) & 0x7f;\n");
2468 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2474 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2475 printf ("\treturn;\n");
2477 printf (" case %d: \n", p
->index
+ 1);
2489 printf (" z = iword & 0xf;\n");
2497 else if (havedecl
== 2)
2499 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2504 (havedecl
== 2 ? " " : ""),
2512 printf (" if (iword & 0x200)\n");
2513 printf (" goto assign_z;\n");
2515 printf (" break;\n");
2519 printf (" default:\n");
2521 printf (" RAISE_EXCEPTION (SIGILL);\n");
2522 printf (" return;\n");
2525 printf (" DSR &= ~0xf1;\n");
2526 printf (" if (res || res_grd)\n");
2527 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2529 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2530 printf (" assign_dc:\n");
2531 printf (" switch (DSR >> 1 & 7)\n");
2533 printf (" case 0: /* Carry Mode */\n");
2534 printf (" DSR |= carry;\n");
2535 printf (" case 1: /* Negative Value Mode */\n");
2536 printf (" DSR |= res_grd >> 7 & 1;\n");
2537 printf (" case 2: /* Zero Value Mode */\n");
2538 printf (" DSR |= DSR >> 6 & 1;\n");
2539 printf (" case 3: /* Overflow mode\n");
2540 printf (" DSR |= overflow >> 4;\n");
2541 printf (" case 4: /* Signed Greater Than Mode */\n");
2542 printf (" DSR |= DSR >> 7 & 1;\n");
2543 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2544 printf (" DSR |= greater_equal >> 7;\n");
2546 printf (" assign_z:\n");
2547 printf (" if (0xa05f >> z & 1)\n");
2549 printf (" RAISE_EXCEPTION (SIGILL);\n");
2550 printf (" return;\n");
2552 printf (" DSP_R (z) = res;\n");
2553 printf (" DSP_GRD (z) = res_grd;\n");
2562 /* verify the table before anything else */
2565 for (p
= tab
; p
->name
; p
++)
2567 /* check that the code field contains 16 bits */
2568 if (strlen (p
->code
) != 16)
2570 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2571 p
->code
, strlen (p
->code
), p
->name
);
2577 /* now generate the requested data */
2580 if (strcmp (av
[1], "-t") == 0)
2584 else if (strcmp (av
[1], "-d") == 0)
2588 else if (strcmp (av
[1], "-s") == 0)
2591 dumptable ("sh_jump_table", 1 << 16, 0);
2593 memset (table
, 0, sizeof table
);
2594 filltable (movsxy_tab
);
2596 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2598 memset (table
, 0, sizeof table
);
2600 dumptable ("ppi_table", 1 << 8, 0);
2602 else if (strcmp (av
[1], "-x") == 0)
2605 filltable (movsxy_tab
);
2608 else if (strcmp (av
[1], "-p") == 0)
2615 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.106843 seconds and 5 git commands to generate.