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
];
52 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
55 " UNDEF(n); /* see #ifdef PARANOID */",
59 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
63 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
65 "SET_SR_T (ult < R[n]);",
67 "SET_SR_T (T || (R[n] < ult));",
70 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
72 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
76 { "0", "", "and #<imm>,R0", "11001001i8*1....",
79 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
82 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
84 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
87 { "", "", "bf <bdisp8>", "10001011i8p1....",
89 " SET_NIP (PC + 4 + (SEXT(i) * 2));",
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
96 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
98 " Delay_Slot (PC + 2);",
102 { "", "", "bra <bdisp12>", "1010i12.........",
103 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
105 "Delay_Slot (PC + 2);",
108 { "", "n", "braf <REG_N>", "0000nnnn00100011",
109 "SET_NIP (PC + 4 + R[n]);",
111 "Delay_Slot (PC + 2);",
114 { "", "", "bsr <bdisp12>", "1011i12.........",
115 "PR = PH2T (PC + 4);",
116 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
118 "Delay_Slot (PC + 2);",
121 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
122 "PR = PH2T (PC) + 4;",
123 "SET_NIP (PC + 4 + R[n]);",
125 "Delay_Slot (PC + 2);",
128 { "", "", "bt <bdisp8>", "10001001i8p1....",
130 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
135 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
137 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
139 " Delay_Slot (PC + 2);",
143 { "", "", "clrmac", "0000000000101000",
148 { "", "", "clrs", "0000000001001000",
152 { "", "", "clrt", "0000000000001000",
156 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
157 "SET_SR_T (R0 == SEXT (i));",
159 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
160 "SET_SR_T (R[n] == R[m]);",
162 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
163 "SET_SR_T (R[n] >= R[m]);",
165 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
166 "SET_SR_T (R[n] > R[m]);",
168 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
169 "SET_SR_T (UR[n] > UR[m]);",
171 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
172 "SET_SR_T (UR[n] >= UR[m]);",
174 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
175 "SET_SR_T (R[n] > 0);",
177 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
178 "SET_SR_T (R[n] >= 0);",
180 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
181 "ult = R[n] ^ R[m];",
182 "SET_SR_T (((ult & 0xff000000) == 0)",
183 " | ((ult & 0xff0000) == 0)",
184 " | ((ult & 0xff00) == 0)",
185 " | ((ult & 0xff) == 0));",
188 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
189 "SET_SR_Q ((R[n] & sbit) != 0);",
190 "SET_SR_M ((R[m] & sbit) != 0);",
191 "SET_SR_T (M != Q);",
194 { "", "", "div0u", "0000000000011001",
200 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
201 "div1 (R, m, n/*, T*/);",
204 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
205 "dmul (1/*signed*/, R[n], R[m]);",
208 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
209 "dmul (0/*unsigned*/, R[n], R[m]);",
212 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
214 "SET_SR_T (R[n] == 0);",
217 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
218 "R[n] = SEXT (R[m]);",
220 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
221 "R[n] = SEXTW (R[m]);",
224 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
225 "R[n] = (R[m] & 0xff);",
227 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
228 "R[n] = (R[m] & 0xffff);",
232 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
233 "FP_UNARY (n, fabs);",
234 "/* FIXME: FR(n) &= 0x7fffffff; */",
238 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
243 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
244 "FP_CMP (n, ==, m);",
247 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
252 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
253 "if (! FPSCR_PR || n & 1)",
254 " RAISE_EXCEPTION (SIGILL);",
268 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
269 "if (! FPSCR_PR || n & 1)",
270 " RAISE_EXCEPTION (SIGILL);",
284 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
286 "/* FIXME: check for DP and (n & 1) == 0? */",
290 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
291 "/* FIXME: not implemented */",
292 "RAISE_EXCEPTION (SIGILL);",
293 "/* FIXME: check for DP and (n & 1) == 0? */",
297 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
298 "SET_FR (n, (float)0.0);",
299 "/* FIXME: check for DP and (n & 1) == 0? */",
303 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
304 "SET_FR (n, (float)1.0);",
305 "/* FIXME: check for DP and (n & 1) == 0? */",
309 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
320 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
323 " SET_DR (n, (double)FPUL);",
326 " SET_FR (n, (float)FPUL);",
331 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
332 "SET_FR (n, FR(m) * FR(0) + FR(n));",
333 "/* FIXME: check for DP and (n & 1) == 0? */",
337 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
340 " int ni = XD_TO_XF (n);",
341 " int mi = XD_TO_XF (m);",
342 " SET_XF (ni + 0, XF (mi + 0));",
343 " SET_XF (ni + 1, XF (mi + 1));",
347 " SET_FR (n, FR (m));",
351 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
360 " WLAT (R[n], FI(m));",
364 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
373 " SET_FI(n, RLAT(R[m]));",
377 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
387 " SET_FI (n, RLAT (R[m]));",
392 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
403 " WLAT (R[n], FI(m));",
407 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
411 " RDAT (R[0]+R[m], n);",
416 " SET_FI(n, RLAT(R[0] + R[m]));",
420 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
424 " WDAT (R[0]+R[n], m);",
429 " WLAT((R[0]+R[n]), FI(m));",
433 /* sh4: See fmov instructions above for move to/from extended fp registers */
436 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
441 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
446 { "", "", "frchg", "1111101111111101",
447 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
451 { "", "", "fschg", "1111001111111101",
452 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
456 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
457 "FP_UNARY(n, sqrt);",
461 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
466 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
469 " if (DR(n) != DR(n)) /* NaN */",
470 " FPUL = 0x80000000;",
472 " FPUL = (int)DR(n);",
475 "if (FR(n) != FR(n)) /* NaN */",
476 " FPUL = 0x80000000;",
478 " FPUL = (int)FR(n);",
482 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
492 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
493 "SET_NIP (PT2H (R[n]));",
495 "Delay_Slot (PC + 2);",
498 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
499 "PR = PH2T (PC + 4);",
501 " gotcall (PR, R[n]);",
502 "SET_NIP (PT2H (R[n]));",
504 "Delay_Slot (PC + 2);",
507 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
509 "/* FIXME: user mode */",
511 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
513 "/* FIXME: user mode */",
515 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
519 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
521 "/* FIXME: user mode */",
524 { "", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
526 "CREG (m) = RLAT (R[n]);",
528 "/* FIXME: user mode */",
530 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
532 "SET_SR (RLAT (R[n]));",
534 "/* FIXME: user mode */",
536 { "", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
538 "SET_MOD (RLAT (R[n]));",
542 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
544 "DBR = RLAT (R[n]);",
546 "/* FIXME: user mode */",
551 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
552 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
554 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
555 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
558 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
561 { "", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
563 "SREG (m) = RLAT(R[n]);",
566 /* sh3e / sh-dsp (lds <REG_N>,DSR) */
567 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
570 /* sh3e / sh-dsp (lds.l @<REG_N>+,DSR) */
571 { "", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
573 "SET_FPSCR (RLAT(R[n]));",
577 { "", "", "ldtlb", "0000000000111000",
578 "/* FIXME: XXX*/ abort();",
581 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
582 "trap (255,R0,memory,maskl,maskw, endianw);",
583 "/* FIXME: mac.l support */",
586 { "", "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 { "n", "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 { "", "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 { "", "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 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
756 "/* FIXME: Not implemented */",
757 "RAISE_EXCEPTION (SIGILL);",
760 { "n", "", "movt <REG_N>", "0000nnnn00101001",
764 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
765 "MACL = ((int)R[n]) * ((int)R[m]);",
768 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
769 "MACL = R[n] * R[m];",
773 /* muls.w - see muls */
774 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
775 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
778 /* mulu.w - see mulu */
779 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
780 "MACL = (((unsigned int)(unsigned short)R[n])",
781 " * ((unsigned int)(unsigned short)R[m]));",
784 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
788 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
790 "SET_SR_T (ult > 0);",
791 "R[n] = ult - R[m];",
792 "SET_SR_T (T || (R[n] > ult));",
795 { "", "", "nop", "0000000000001001",
799 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
803 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
804 "/* FIXME: Not implemented */",
805 "RAISE_EXCEPTION (SIGILL);",
808 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
809 "/* FIXME: Not implemented */",
810 "RAISE_EXCEPTION (SIGILL);",
813 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
814 "RSBAT (R[n]); /* Take exceptions like byte load. */",
815 "/* FIXME: Cache not implemented */",
818 { "0", "", "or #<imm>,R0", "11001011i8*1....",
821 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
824 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
826 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
829 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
830 "/* Except for the effect on the cache - which is not simulated -",
831 " this is like a nop. */",
834 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
836 "R[n] = (R[n] << 1) | T;",
840 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
842 "R[n] = (UR[n] >> 1) | (T << 31);",
846 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
847 "SET_SR_T (R[n] < 0);",
852 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
853 "SET_SR_T (R[n] & 1);",
854 "R[n] = UR[n] >> 1;",
855 "R[n] |= (T << 31);",
858 { "", "", "rte", "0000000000101011",
862 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
864 "SET_SR (RLAT (R[15]) & 0x3f3);",
866 "Delay_Slot (PC + 2);",
869 "SET_NIP (PT2H (SPC));",
871 "Delay_Slot (PC + 2);",
875 { "", "", "rts", "0000000000001011",
876 "SET_NIP (PT2H (PR));",
878 "Delay_Slot (PC + 2);",
882 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
885 { "", "n", "setrc #<imm>", "10000010i8*1....",
886 /* It would be more realistic to let loop_start point to some static
887 memory that contains an illegal opcode and then give a bus error when
888 the loop is eventually encountered, but it seems not only simpler,
889 but also more debugging-friendly to just catch the failure here. */
890 "if (BUSERROR (RS | RE, maskw))",
891 " RAISE_EXCEPTION (SIGILL);",
894 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
895 " CHECK_INSN_PTR (insn_ptr);",
899 { "", "", "sets", "0000000001011000",
903 { "", "", "sett", "0000000000011000",
907 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
908 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
911 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
912 "SET_SR_T (R[n] < 0);",
916 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
917 "SET_SR_T (R[n] & 1);",
921 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
922 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
925 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
926 "SET_SR_T (R[n] < 0);",
930 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
933 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
936 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
940 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
941 "SET_SR_T (R[n] & 1);",
942 "R[n] = UR[n] >> 1;",
945 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
946 "R[n] = UR[n] >> 2;",
948 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
949 "R[n] = UR[n] >> 8;",
951 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
952 "R[n] = UR[n] >> 16;",
955 { "", "", "sleep", "0000000000011011",
957 "trap (0xc3, R0, 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....",
1036 "long imm = 0xff & i;",
1039 "if (i<20||i==34||i==0xc3)",
1040 " trap(i,R,memory,maskl,maskw,endianw);",
1043 " WLAT(R[15],GET_SR());",
1045 " WLAT(R[15],PC+2);",
1046 " PC=RLAT(VBR+(imm<<2))-2;",
1052 " trap (i, R, memory, maskl, maskw,endianw);",
1054 "else if (i < 20 || i==34 || i==0xc3)",
1055 " trap (i, R, memory, maskl, maskw,endianw);",
1056 "else if (!SR_BL) {",
1057 " /* FIXME: TRA = (imm << 2); */",
1059 " SPC = PH2T (PC + 2);",
1060 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1061 " /* FIXME: EXPEVT = 0x00000160; */",
1062 " SET_NIP (PT2H (VBR + 0x00000100));",
1067 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1068 "SET_SR_T ((R[n] & R[m]) == 0);",
1070 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1071 "SET_SR_T ((R0 & i) == 0);",
1073 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1075 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1078 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1081 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1084 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1086 "ult = RBAT (GBR+R0);",
1088 "WBAT (GBR + R0, ult);",
1091 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1092 "R[n] = (((R[n] >> 16) & 0xffff)",
1093 " | ((R[m] << 16) & 0xffff0000));",
1097 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1098 "divl(0,R[n],R[m]);",
1100 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1101 "divl(0,R[n],R[m]);",
1109 /* If this is disabled, the simulator speeds up by about 12% on a
1110 450 MHz PIII - 9% with ACE_FAST.
1111 Maybe we should have separate simulator loops? */
1113 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1116 "DSP_R (m) = RSWAT (R[n]) << 16;",
1117 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1119 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1121 "DSP_R (m) = RSWAT (R[n]) << 16;",
1122 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1124 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1126 "DSP_R (m) = RSWAT (R[n]) << 16;",
1127 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1130 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1132 "DSP_R (m) = RSWAT (R[n]) << 16;",
1133 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1136 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1139 "DSP_R (m) = RSWAT (R[n]);",
1141 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1143 "DSP_R (m) = RSWAT (R[n]);",
1145 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1147 "DSP_R (m) = RSWAT (R[n]);",
1150 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1152 "DSP_R (m) = RSWAT (R[n]);",
1155 { "n", "n", "<DSP_REG_M>,movs.w @-<REG_N>", "111101NNMMMM0001",
1158 "WWAT (R[n], DSP_R (m) >> 16);",
1160 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1162 "WWAT (R[n], DSP_R (m) >> 16);",
1164 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1166 "WWAT (R[n], DSP_R (m) >> 16);",
1169 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1171 "WWAT (R[n], DSP_R (m) >> 16);",
1174 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1177 "WWAT (R[n], SEXT (DSP_R (m)));",
1179 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1181 "WWAT (R[n], SEXT (DSP_R (m)));",
1183 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1185 "WWAT (R[n], SEXT (DSP_R (m)));",
1188 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1190 "WWAT (R[n], SEXT (DSP_R (m)));",
1193 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1196 "DSP_R (m) = RLAT (R[n]);",
1197 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1199 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1201 "DSP_R (m) = RLAT (R[n]);",
1202 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1204 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1206 "DSP_R (m) = RLAT (R[n]);",
1207 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1210 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1212 "DSP_R (m) = RLAT (R[n]);",
1213 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1216 { "n", "n", "<DSP_REG_M>,movs.l @-<REG_N>", "111101NNMMMM0011",
1219 "WLAT (R[n], DSP_R (m));",
1221 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1223 "WLAT (R[n], DSP_R (m));",
1225 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1227 "WLAT (R[n], DSP_R (m));",
1230 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1232 "WLAT (R[n], DSP_R (m));",
1235 { "n", "n", "<DSP_GRD_M>,movs.l @-<REG_N>", "111101NNGGGG0011",
1238 "WLAT (R[n], SEXT (DSP_R (m)));",
1240 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1242 "WLAT (R[n], SEXT (DSP_R (m)));",
1244 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1246 "WLAT (R[n], SEXT (DSP_R (m)));",
1249 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1251 "WLAT (R[n], SEXT (DSP_R (m)));",
1254 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1255 "DSP_R (m) = RSWAT (R[n]) << 16;",
1256 "iword &= 0xfd53; goto top;",
1258 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1259 "DSP_R (m) = RSWAT (R[n]) << 16;",
1260 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1261 "iword &= 0xfd53; goto top;",
1263 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1264 "DSP_R (m) = RSWAT (R[n]) << 16;",
1265 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1266 "iword &= 0xfd53; goto top;",
1268 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1269 "WWAT (R[n], DSP_R (m) >> 16);",
1270 "iword &= 0xfd53; goto top;",
1272 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1273 "WWAT (R[n], DSP_R (m) >> 16);",
1274 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1275 "iword &= 0xfd53; goto top;",
1277 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101000",
1278 "WWAT (R[n], DSP_R (m) >> 16);",
1279 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1280 "iword &= 0xfd53; goto top;",
1282 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1283 "DSP_R (m) = RSWAT (R[n]) << 16;",
1285 { "n", "n", "movy.w @<REG_x>+,<DSP_YY>", "111100yyYY000010",
1286 "DSP_R (m) = RSWAT (R[n]) << 16;",
1287 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1289 { "n", "n9","movy.w @<REG_x>+REG_9,<DSP_YY>", "111100yyYY000010",
1290 "DSP_R (m) = RSWAT (R[n]) << 16;",
1291 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1293 { "", "n", "movy.w <DSP_Aa>,@<REG_x>", "111100yyAA010001",
1294 "WWAT (R[n], DSP_R (m) >> 16);",
1296 { "n", "n", "movy.w <DSP_Aa>,@<REG_x>+", "111100yyAA010010",
1297 "WWAT (R[n], DSP_R (m) >> 16);",
1298 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1300 { "n", "n9", "movy.w <DSP_Aa>,@<REG_x>+REG_9", "111100yyAA010010",
1301 "WWAT (R[n], DSP_R (m) >> 16);",
1302 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1304 { "", "", "nopx nopy", "1111000000000000",
1307 { "", "", "ppi", "1111100000000000",
1308 "ppi_insn (RIAT (nip));",
1310 "iword &= 0xf7ff; goto top;",
1317 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1318 "int Sz = DSP_R (z) & 0xffff0000;",
1322 "else if (i >= 128 - 16)",
1323 " res = Sz >> 128 - i;",
1326 " RAISE_EXCEPTION (SIGILL);",
1329 "res &= 0xffff0000;",
1333 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1334 "int Sz = DSP_R (z);",
1335 "int Sz_grd = GET_DSP_GRD (z);",
1347 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1349 " res_grd = SEXT (res_grd);",
1350 " carry = res_grd & 1;",
1352 "else if (i >= 96)",
1357 " res_grd = SIGN32 (Sz_grd);",
1362 " res = Sz >> i | Sz_grd << 32 - i;",
1363 " res_grd = Sz_grd >> i;",
1365 " carry = Sz >> (i - 1) & 1;",
1369 " RAISE_EXCEPTION (SIGILL);",
1372 "COMPUTE_OVERFLOW;",
1373 "greater_equal = 0;",
1375 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1376 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1377 "if (res == 0x80000000)",
1378 " res = 0x7fffffff;",
1380 "DSP_GRD (g) = SIGN32 (res);",
1383 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1384 "int Sx = DSP_R (x);",
1385 "int Sx_grd = GET_DSP_GRD (x);",
1386 "int Sy = DSP_R (y);",
1387 "int Sy_grd = SIGN32 (Sy);",
1389 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1390 "if (res == 0x80000000)",
1391 " res = 0x7fffffff;",
1393 "DSP_GRD (g) = SIGN32 (res);",
1397 "carry = (unsigned) res > (unsigned) Sx;",
1398 "res_grd = Sx_grd - Sy_grd - carry;",
1399 "COMPUTE_OVERFLOW;",
1402 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1403 "int Sx = DSP_R (x);",
1404 "int Sx_grd = GET_DSP_GRD (x);",
1405 "int Sy = DSP_R (y);",
1406 "int Sy_grd = SIGN32 (Sy);",
1408 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1409 "if (res == 0x80000000)",
1410 " res = 0x7fffffff;",
1412 "DSP_GRD (g) = SIGN32 (res);",
1416 "carry = (unsigned) res < (unsigned) Sx;",
1417 "res_grd = Sx_grd + Sy_grd + carry;",
1418 "COMPUTE_OVERFLOW;",
1420 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1421 "int Sx = DSP_R (x);",
1422 "int Sx_grd = GET_DSP_GRD (x);",
1423 "int Sy = DSP_R (y);",
1424 "int Sy_grd = SIGN32 (Sy);",
1426 "res = Sx - Sy - (DSR & 1);",
1427 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1428 "res_grd = Sx_grd + Sy_grd + carry;",
1429 "COMPUTE_OVERFLOW;",
1432 "if (res || res_grd)\n",
1433 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1435 " DSR |= DSR_MASK_Z | overflow;\n",
1439 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1440 "int Sx = DSP_R (x);",
1441 "int Sx_grd = GET_DSP_GRD (x);",
1442 "int Sy = DSP_R (y);",
1443 "int Sy_grd = SIGN32 (Sy);",
1445 "res = Sx + Sy + (DSR & 1);",
1446 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1447 "res_grd = Sx_grd + Sy_grd + carry;",
1448 "COMPUTE_OVERFLOW;",
1451 "if (res || res_grd)\n",
1452 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1454 " DSR |= DSR_MASK_Z | overflow;\n",
1458 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1459 "int Sx = DSP_R (x);",
1460 "int Sx_grd = GET_DSP_GRD (x);",
1461 "int Sy = DSP_R (y);",
1462 "int Sy_grd = SIGN32 (Sy);",
1464 "z = 17; /* Ignore result. */",
1466 "carry = (unsigned) res > (unsigned) Sx;",
1467 "res_grd = Sx_grd - Sy_grd - carry;",
1468 "COMPUTE_OVERFLOW;",
1471 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1473 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1475 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1477 "res_grd = GET_DSP_GRD (x);",
1483 " carry = (res != 0); /* The manual has a bug here. */",
1484 " res_grd = -res_grd - carry;",
1486 "COMPUTE_OVERFLOW;",
1487 "/* ??? The re-computing of overflow after",
1488 " saturation processing is specific to pabs. */",
1489 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1492 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1493 "int Sx = DSP_R (x);",
1494 "int Sx_grd = GET_DSP_GRD (x);",
1496 "res = Sx + 0x8000;",
1497 "carry = (unsigned) res < (unsigned) Sx;",
1498 "res_grd = Sx_grd + carry;",
1499 "COMPUTE_OVERFLOW;",
1502 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1506 "greater_equal = DSR_MASK_G;",
1516 " res = 0x7fffffff;",
1519 " overflow = DSR_MASK_V;",
1520 " greater_equal = 0;",
1525 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1526 "int Sy = DSP_R (y);",
1527 "int Sy_grd = SIGN32 (Sy);",
1529 "res = Sy + 0x8000;",
1530 "carry = (unsigned) res < (unsigned) Sy;",
1531 "res_grd = Sy_grd + carry;",
1532 "COMPUTE_OVERFLOW;",
1535 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1536 "int Sx = DSP_R (x) & 0xffff0000;",
1537 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1541 "else if (Sy >= 128 - 16)",
1542 " res = Sx >> 128 - Sy;",
1545 " RAISE_EXCEPTION (SIGILL);",
1548 "goto cond_logical;",
1550 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1551 "int Sx = DSP_R (x);",
1552 "int Sx_grd = GET_DSP_GRD (x);",
1553 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1565 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1567 " res_grd = SEXT (res_grd);",
1568 " carry = res_grd & 1;",
1570 "else if (Sy >= 96)",
1575 " res_grd = SIGN32 (Sx_grd);",
1580 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1581 " res_grd = Sx_grd >> Sy;",
1583 " carry = Sx >> (Sy - 1) & 1;",
1587 " RAISE_EXCEPTION (SIGILL);",
1590 "COMPUTE_OVERFLOW;",
1591 "greater_equal = 0;",
1593 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
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) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1606 "int Sx = DSP_R (x);",
1607 "int Sx_grd = GET_DSP_GRD (x);",
1608 "int Sy = DSP_R (y);",
1609 "int Sy_grd = SIGN32 (Sy);",
1612 "carry = (unsigned) res < (unsigned) Sx;",
1613 "res_grd = Sx_grd + Sy_grd + carry;",
1614 "COMPUTE_OVERFLOW;",
1617 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1618 "res = DSP_R (x) & DSP_R (y);",
1620 "res &= 0xffff0000;",
1622 "if (iword & 0x200)\n",
1623 " goto assign_z;\n",
1627 "greater_equal = 0;",
1630 " DSR |= res >> 26 & DSR_MASK_N;\n",
1632 " DSR |= DSR_MASK_Z;\n",
1633 "goto assign_dc;\n",
1635 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1636 "res = DSP_R (x) ^ DSP_R (y);",
1637 "goto cond_logical;",
1639 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1640 "res = DSP_R (x) | DSP_R (y);",
1641 "goto cond_logical;",
1643 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1644 "int Sx = DSP_R (x);",
1645 "int Sx_grd = GET_DSP_GRD (x);",
1647 "res = Sx - 0x10000;",
1648 "carry = res > Sx;",
1649 "res_grd = Sx_grd - carry;",
1650 "COMPUTE_OVERFLOW;",
1652 "res &= 0xffff0000;",
1654 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1655 "int Sx = DSP_R (x);",
1656 "int Sx_grd = GET_DSP_GRD (x);",
1658 "res = Sx + 0x10000;",
1659 "carry = res < Sx;",
1660 "res_grd = Sx_grd + carry;",
1661 "COMPUTE_OVERFLOW;",
1663 "res &= 0xffff0000;",
1665 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1666 "int Sy = DSP_R (y);",
1667 "int Sy_grd = SIGN32 (Sy);",
1669 "res = Sy - 0x10000;",
1670 "carry = res > Sy;",
1671 "res_grd = Sy_grd - carry;",
1672 "COMPUTE_OVERFLOW;",
1674 "res &= 0xffff0000;",
1676 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1677 "int Sy = DSP_R (y);",
1678 "int Sy_grd = SIGN32 (Sy);",
1680 "res = Sy + 0x10000;",
1681 "carry = res < Sy;",
1682 "res_grd = Sy_grd + carry;",
1683 "COMPUTE_OVERFLOW;",
1685 "res &= 0xffff0000;",
1687 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1692 "greater_equal = 1;",
1694 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1695 "unsigned Sx = DSP_R (x);",
1696 "int Sx_grd = GET_DSP_GRD (x);",
1701 " Sx_grd = ~Sx_grd;",
1715 " if (Sx & ~0 << i)",
1723 "res_grd = SIGN32 (res);",
1728 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1729 "unsigned Sy = DSP_R (y);",
1738 " if (Sy & ~0 << i)",
1746 "res_grd = SIGN32 (res);",
1751 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1752 "int Sx = DSP_R (x);",
1753 "int Sx_grd = GET_DSP_GRD (x);",
1756 "carry = res != 0;",
1757 "res_grd = 0 - Sx_grd - carry;",
1758 "COMPUTE_OVERFLOW;",
1761 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1763 "res_grd = GET_DSP_GRD (x);",
1765 "COMPUTE_OVERFLOW;",
1768 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1769 "int Sy = DSP_R (y);",
1770 "int Sy_grd = SIGN32 (Sy);",
1773 "carry = res != 0;",
1774 "res_grd = 0 - Sy_grd - carry;",
1775 "COMPUTE_OVERFLOW;",
1778 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1780 "res_grd = SIGN32 (res);",
1782 "COMPUTE_OVERFLOW;",
1785 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1787 "res_grd = SIGN32 (res);",
1790 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1792 "res_grd = SIGN32 (res);",
1795 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1796 "if (0xa05f >> z & 1)",
1797 " RAISE_EXCEPTION (SIGILL);",
1799 " MACH = DSP_R (z);",
1802 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1803 "if (0xa05f >> z & 1)",
1804 " RAISE_EXCEPTION (SIGILL);",
1806 " MACL = DSP_R (z) = res;",
1812 /* Tables of things to put into enums for sh-opc.h */
1813 static char *nibble_type_list
[] =
1848 char *arg_type_list
[] =
1882 make_enum_list (name
, s
)
1887 printf ("typedef enum {\n");
1890 printf ("\t%s,\n", *s
);
1894 printf ("} %s;\n", name
);
1906 memcpy (bufa
, a
->code
, 4);
1907 memcpy (bufa
+ 4, a
->code
+ 12, 4);
1910 memcpy (bufb
, b
->code
, 4);
1911 memcpy (bufb
+ 4, b
->code
+ 12, 4);
1913 diff
= strcmp (bufa
, bufb
);
1914 /* Stabilize the sort, so that later entries can override more general
1915 preceding entries. */
1916 return diff
? diff
: a
- b
;
1930 qsort (tab
, len
, sizeof (*p
), qfunc
);
1938 for (p
= tab
; p
->name
; p
++)
1940 printf ("%s %-30s\n", p
->code
, p
->name
);
1946 /* Convert a string of 4 binary digits into an int */
1966 static unsigned char table
[1 << 16];
1968 /* Take an opcode expand all varying fields in it out and fill all the
1969 right entries in 'table' with the opcode index*/
1972 expand_opcode (shift
, val
, i
, s
)
1994 val
|= bton (s
) << shift
;
1995 if (s
[2] == '0' || s
[2] == '1')
1996 expand_opcode (shift
- 4, val
, i
, s
+ 4);
1997 else if (s
[2] == 'N')
1998 for (j
= 0; j
< 4; j
++)
1999 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2000 else if (s
[2] == 'x')
2001 for (j
= 0; j
< 4; j
+= 2)
2002 for (m
= 0; m
< 32; m
++)
2004 /* Ignore illegal nopy */
2005 if ((m
& 7) == 0 && m
!= 0)
2007 mv
= m
& 3 | (m
& 4) << 2 | (m
& 8) << 3 | (m
& 16) << 4;
2008 expand_opcode (shift
- 4, val
| mv
| (j
<< shift
), i
,
2011 else if (s
[2] == 'y')
2012 for (j
= 0; j
< 2; j
++)
2013 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2018 for (j
= 0; j
< 16; j
++)
2020 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2025 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2026 for (j
= 5; j
< 16; j
++)
2028 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2032 for (j
= 13; j
<= 15; j
+=2)
2033 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2036 /* System registers mach, macl, pr: */
2037 for (j
= 0; j
< 3; j
++)
2038 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2039 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2040 for (j
= 5; j
< 12; j
++)
2041 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2045 val
|= bton (s
) << shift
;
2046 for (j
= 0; j
< 16; j
+= 8)
2047 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2051 val
|= bton (s
) << shift
;
2052 for (j
= 0; j
< 8; j
+= 4)
2053 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2057 for (j
= 0; j
< (1 << (shift
+ 4)); j
++)
2065 /* Print the jump table used to index an opcode into a switch
2069 dumptable (name
, size
, start
)
2079 printf ("unsigned char %s[%d]={\n", name
, size
);
2080 while (i
< start
+ size
)
2084 printf ("/* 0x%x */\n", i
);
2091 printf ("%2d", table
[i
+ j
+ k
]);
2110 static int index
= 1;
2113 for (; p
->name
; p
++)
2116 expand_opcode (12, 0, p
->index
, p
->code
);
2120 /* Table already contais all the switch case tags for 16-bit opcode double
2121 data transfer (ddt) insns, and the switch case tag for processing parallel
2122 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2123 latter tag to represent all combinations of ppi with ddt. */
2129 for (i
= 0xf000; i
< 0xf400; i
++)
2131 table
[i
+ 0x800] = table
[0xf800];
2138 for (; p
->name
; p
++)
2147 printf (" /* %s %s */\n", p
->name
, p
->code
);
2148 printf (" case %d: \n", p
->index
);
2163 printf (" int n = (iword >>8) & 0xf;\n");
2168 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2172 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2177 printf (" int n = ((iword >> 8) & 1) + 4;\n");
2186 printf (" int m = (iword >>4) & 0xf;\n");
2190 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2194 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2198 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2202 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2207 printf (" int i = (iword & 0x");
2242 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2243 sextbit
- 1, sextbit
- 1);
2247 printf (" TB(m,n);\n");
2249 printf (" TL(m);\n");
2251 printf (" TL(n);\n");
2256 for (r
= p
->refs
; *r
; r
++)
2258 if (*r
== '0') printf(" CREF(0);\n");
2259 if (*r
== '8') printf(" CREF(8);\n");
2260 if (*r
== '9') printf(" CREF(9);\n");
2261 if (*r
== 'n') printf(" CREF(n);\n");
2262 if (*r
== 'm') printf(" CREF(m);\n");
2267 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2271 printf (" %s\n", p
->stuff
[j
]);
2279 for (r
= p
->defs
; *r
; r
++)
2281 if (*r
== '0') printf(" CDEF(0);\n");
2282 if (*r
== 'n') printf(" CDEF(n);\n");
2283 if (*r
== 'm') printf(" CDEF(m);\n");
2287 printf (" break;\n");
2296 printf (" switch (jump_table[iword]) {\n");
2298 gensim_caselist (tab
);
2299 gensim_caselist (movsxy_tab
);
2301 printf (" default:\n");
2303 printf (" RAISE_EXCEPTION (SIGILL);\n");
2314 for (p
= tab
; p
->name
; p
++)
2317 printf ("#define OPC_");
2321 if (isalpha(*s
)) printf("%c", *s
);
2322 if (*s
== ' ') printf("_");
2323 if (*s
== '@') printf("ind_");
2324 if (*s
== ',') printf("_");
2327 printf(" %d\n",p
->index
);
2331 static int ppi_index
;
2333 /* Take an ppi code, expand all varying fields in it and fill all the
2334 right entries in 'table' with the opcode index. */
2337 expand_ppi_code (val
, i
, s
)
2348 /* The last eight bits are disregarded for the switch table. */
2366 expand_ppi_code (val
, i
, s
);
2373 expand_ppi_code (val
, ppi_index
++, s
);
2375 expand_ppi_code (val
, i
, s
);
2388 for (p
= ppi_tab
; p
->name
; p
++)
2390 p
->index
= ppi_index
++;
2391 expand_ppi_code (0, p
->index
, p
->code
);
2400 printf ("#define DSR_MASK_G 0x80\n");
2401 printf ("#define DSR_MASK_Z 0x40\n");
2402 printf ("#define DSR_MASK_N 0x20\n");
2403 printf ("#define DSR_MASK_V 0x10\n");
2405 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2406 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2407 printf (" if (overflow && S) \\\n");
2409 printf (" if (res_grd & 0x80) \\\n");
2411 printf (" res = 0x80000000; \\\n");
2412 printf (" res_grd |= 0xff; \\\n");
2414 printf (" else \\\n");
2416 printf (" res = 0x7fffffff; \\\n");
2417 printf (" res_grd &= ~0xff; \\\n");
2419 printf (" overflow = 0; \\\n");
2421 printf ("} while (0)\n");
2423 printf ("#define ADD_SUB_GE \\\n");
2424 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2426 printf ("static void\n");
2427 printf ("ppi_insn (iword)\n");
2428 printf (" int iword;\n");
2430 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2431 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2432 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2433 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2434 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2435 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2437 printf (" int z;\n");
2438 printf (" int res, res_grd;\n");
2439 printf (" int carry, overflow, greater_equal;\n");
2441 printf (" switch (ppi_table[iword >> 8]) {\n");
2443 for (; p
->name
; p
++)
2451 printf (" /* %s %s */\n", p
->name
, p
->code
);
2452 printf (" case %d: \n", p
->index
);
2455 for (shift
= 16; *s
; )
2460 printf (" int i = (iword >> 4) & 0x7f;\n");
2470 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2476 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2477 printf ("\tbreak;\n");
2479 printf (" case %d: \n", p
->index
+ 1);
2491 printf (" z = iword & 0xf;\n");
2499 else if (havedecl
== 2)
2501 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2506 (havedecl
== 2 ? " " : ""),
2514 printf (" if (iword & 0x200)\n");
2515 printf (" goto assign_z;\n");
2517 printf (" break;\n");
2521 printf (" default:\n");
2523 printf (" RAISE_EXCEPTION (SIGILL);\n");
2524 printf (" return;\n");
2527 printf (" DSR &= ~0xf1;\n");
2528 printf (" if (res || res_grd)\n");
2529 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2531 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2532 printf (" assign_dc:\n");
2533 printf (" switch (DSR >> 1 & 7)\n");
2535 printf (" case 0: /* Carry Mode */\n");
2536 printf (" DSR |= carry;\n");
2537 printf (" case 1: /* Negative Value Mode */\n");
2538 printf (" DSR |= res_grd >> 7 & 1;\n");
2539 printf (" case 2: /* Zero Value Mode */\n");
2540 printf (" DSR |= DSR >> 6 & 1;\n");
2541 printf (" case 3: /* Overflow mode\n");
2542 printf (" DSR |= overflow >> 4;\n");
2543 printf (" case 4: /* Signed Greater Than Mode */\n");
2544 printf (" DSR |= DSR >> 7 & 1;\n");
2545 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2546 printf (" DSR |= greater_equal >> 7;\n");
2548 printf (" assign_z:\n");
2549 printf (" if (0xa05f >> z & 1)\n");
2551 printf (" RAISE_EXCEPTION (SIGILL);\n");
2552 printf (" return;\n");
2554 printf (" DSP_R (z) = res;\n");
2555 printf (" DSP_GRD (z) = res_grd;\n");
2564 /* verify the table before anything else */
2567 for (p
= tab
; p
->name
; p
++)
2569 /* check that the code field contains 16 bits */
2570 if (strlen (p
->code
) != 16)
2572 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2573 p
->code
, strlen (p
->code
), p
->name
);
2579 /* now generate the requested data */
2582 if (strcmp (av
[1], "-t") == 0)
2586 else if (strcmp (av
[1], "-d") == 0)
2590 else if (strcmp (av
[1], "-s") == 0)
2593 dumptable ("sh_jump_table", 1 << 16, 0);
2595 memset (table
, 0, sizeof table
);
2596 filltable (movsxy_tab
);
2598 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2600 memset (table
, 0, sizeof table
);
2602 dumptable ("ppi_table", 1 << 8, 0);
2604 else if (strcmp (av
[1], "-x") == 0)
2607 filltable (movsxy_tab
);
2610 else if (strcmp (av
[1], "-p") == 0)
2617 fprintf (stderr
, "Opcode table generation no longer supported.\n");