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 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
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 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
358 " WLAT (R[n], FI(m));",
362 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
371 " SET_FI(n, RLAT(R[m]));",
375 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
385 " SET_FI (n, RLAT (R[m]));",
390 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
401 " WLAT (R[n], FI(m));",
405 { "", "", "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 { "", "", "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",
445 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
449 { "", "", "fschg", "1111001111111101",
450 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
454 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
455 "FP_UNARY(n, sqrt);",
459 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
464 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
467 " if (DR(n) != DR(n)) /* NaN */",
468 " FPUL = 0x80000000;",
470 " FPUL = (int)DR(n);",
473 "if (FR(n) != FR(n)) /* NaN */",
474 " FPUL = 0x80000000;",
476 " FPUL = (int)FR(n);",
480 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
490 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
491 "SET_NIP (PT2H (R[n]));",
493 "Delay_Slot (PC + 2);",
496 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
497 "PR = PH2T (PC + 4);",
499 " gotcall (PR, R[n]);",
500 "SET_NIP (PT2H (R[n]));",
502 "Delay_Slot (PC + 2);",
505 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
507 "/* FIXME: user mode */",
509 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
511 "/* FIXME: user mode */",
513 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
517 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
519 "/* FIXME: user mode */",
522 { "", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
524 "CREG (m) = RLAT (R[n]);",
526 "/* FIXME: user mode */",
528 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
530 "SET_SR (RLAT (R[n]));",
532 "/* FIXME: user mode */",
534 { "", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
536 "SET_MOD (RLAT (R[n]));",
540 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
542 "DBR = RLAT (R[n]);",
544 "/* FIXME: user mode */",
549 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
550 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
552 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
553 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
556 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
559 { "", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
561 "SREG (m) = RLAT(R[n]);",
564 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
565 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
568 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
569 { "", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
571 "SET_FPSCR (RLAT(R[n]));",
575 { "", "", "ldtlb", "0000000000111000",
576 "/* FIXME: XXX*/ abort();",
579 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
580 "trap (255, R0, PC, memory, maskl, maskw, endianw);",
581 "/* FIXME: mac.l support */",
584 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
585 "macw(R0,memory,n,m,endianw);",
588 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
591 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
595 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
597 "R0 = RSBAT (i + GBR);",
600 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
602 "R0 = RSBAT (i + R[m]);",
605 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
607 "R[n] = RSBAT (R0 + R[m]);",
610 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
612 "R[n] = RSBAT (R[m]);",
616 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
618 "WBAT (R[n], R[m]);",
620 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
622 "WBAT (i + GBR, R0);",
624 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
626 "WBAT (i + R[m], R0);",
628 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
630 "WBAT (R[n] + R0, R[m]);",
632 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
635 "WBAT (R[n], R[m]);",
637 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
639 "R[n] = RSBAT (R[m]);",
643 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
645 "R0 = RLAT (i + GBR);",
648 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
650 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
653 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
655 "R[n] = RLAT (i + R[m]);",
658 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
660 "R[n] = RLAT (R0 + R[m]);",
663 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
665 "R[n] = RLAT (R[m]);",
669 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
671 "R[n] = RLAT (R[m]);",
674 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
676 "WLAT (i + GBR, R0);",
678 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
680 "WLAT (i + R[n], R[m]);",
682 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
684 "WLAT (R0 + R[n], R[m]);",
686 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
689 "WLAT (R[n], R[m]);",
691 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
693 "WLAT (R[n], R[m]);",
696 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
698 ";R0 = RSWAT (i + GBR);",
701 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
703 "R[n] = RSWAT (PH2T (PC + 4 + i));",
706 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
708 "R0 = RSWAT (i + R[m]);",
711 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
713 "R[n] = RSWAT (R0 + R[m]);",
716 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
718 "R[n] = RSWAT (R[m]);",
722 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
724 "R[n] = RSWAT (R[m]);",
727 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
729 "WWAT (i + GBR, R0);",
731 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
733 "WWAT (i + R[m], R0);",
735 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
737 "WWAT (R0 + R[n], R[m]);",
739 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
742 "WWAT (R[n], R[m]);",
744 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
746 "WWAT (R[n], R[m]);",
749 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
750 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
753 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
754 "/* FIXME: Not implemented */",
755 "RAISE_EXCEPTION (SIGILL);",
758 { "n", "", "movt <REG_N>", "0000nnnn00101001",
762 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
763 "MACL = ((int)R[n]) * ((int)R[m]);",
766 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
767 "MACL = R[n] * R[m];",
771 /* muls.w - see muls */
772 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
773 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
776 /* mulu.w - see mulu */
777 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
778 "MACL = (((unsigned int)(unsigned short)R[n])",
779 " * ((unsigned int)(unsigned short)R[m]));",
782 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
786 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
788 "SET_SR_T (ult > 0);",
789 "R[n] = ult - R[m];",
790 "SET_SR_T (T || (R[n] > ult));",
793 { "", "", "nop", "0000000000001001",
797 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
801 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
802 "/* FIXME: Not implemented */",
803 "RAISE_EXCEPTION (SIGILL);",
806 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
807 "/* FIXME: Not implemented */",
808 "RAISE_EXCEPTION (SIGILL);",
811 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
812 "RSBAT (R[n]); /* Take exceptions like byte load. */",
813 "/* FIXME: Cache not implemented */",
816 { "0", "", "or #<imm>,R0", "11001011i8*1....",
819 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
822 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
824 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
827 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
828 "/* Except for the effect on the cache - which is not simulated -",
829 " this is like a nop. */",
832 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
834 "R[n] = (R[n] << 1) | T;",
838 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
840 "R[n] = (UR[n] >> 1) | (T << 31);",
844 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
845 "SET_SR_T (R[n] < 0);",
850 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
851 "SET_SR_T (R[n] & 1);",
852 "R[n] = UR[n] >> 1;",
853 "R[n] |= (T << 31);",
856 { "", "", "rte", "0000000000101011",
860 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
862 "SET_SR (RLAT (R[15]) & 0x3f3);",
864 "Delay_Slot (PC + 2);",
867 "SET_NIP (PT2H (SPC));",
869 "Delay_Slot (PC + 2);",
873 { "", "", "rts", "0000000000001011",
874 "SET_NIP (PT2H (PR));",
876 "Delay_Slot (PC + 2);",
880 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
883 { "", "n", "setrc #<imm>", "10000010i8*1....",
884 /* It would be more realistic to let loop_start point to some static
885 memory that contains an illegal opcode and then give a bus error when
886 the loop is eventually encountered, but it seems not only simpler,
887 but also more debugging-friendly to just catch the failure here. */
888 "if (BUSERROR (RS | RE, maskw))",
889 " RAISE_EXCEPTION (SIGILL);",
892 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
893 " CHECK_INSN_PTR (insn_ptr);",
897 { "", "", "sets", "0000000001011000",
901 { "", "", "sett", "0000000000011000",
905 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
906 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
909 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
910 "SET_SR_T (R[n] < 0);",
914 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
915 "SET_SR_T (R[n] & 1);",
919 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
920 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
923 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
924 "SET_SR_T (R[n] < 0);",
928 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
931 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
934 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
938 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
939 "SET_SR_T (R[n] & 1);",
940 "R[n] = UR[n] >> 1;",
943 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
944 "R[n] = UR[n] >> 2;",
946 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
947 "R[n] = UR[n] >> 8;",
949 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
950 "R[n] = UR[n] >> 16;",
953 { "", "", "sleep", "0000000000011011",
954 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
957 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
962 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
965 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
969 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
972 "WLAT (R[n], CREG (m));",
975 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
980 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
987 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
990 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
993 "WLAT (R[n], SREG (m));",
996 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1000 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1002 "SET_SR_T (ult > R[n]);",
1003 "R[n] = ult - R[m];",
1004 "SET_SR_T (T || (R[n] > ult));",
1007 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1008 "ult = R[n] - R[m];",
1009 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1013 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1014 "R[n] = ((R[m] & 0xffff0000)",
1015 " | ((R[m] << 8) & 0xff00)",
1016 " | ((R[m] >> 8) & 0x00ff));",
1018 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1019 "R[n] = (((R[m] << 16) & 0xffff0000)",
1020 " | ((R[m] >> 16) & 0x00ffff));",
1023 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1025 "ult = RBAT(R[n]);",
1026 "SET_SR_T (ult == 0);",
1027 "WBAT(R[n],ult|0x80);",
1030 { "0", "", "trapa #<imm>", "11000011i8*1....",
1031 "long imm = 0xff & i;",
1032 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1033 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1038 " WLAT (R[15], GET_SR());",
1040 " WLAT (R[15], PH2T (PC + 2));",
1042 "else if (!SR_BL) {",
1044 " SPC = PH2T (PC + 2);",
1045 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1046 " /* FIXME: EXPEVT = 0x00000160; */",
1048 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1052 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1053 "SET_SR_T ((R[n] & R[m]) == 0);",
1055 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1056 "SET_SR_T ((R0 & i) == 0);",
1058 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1060 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1063 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1066 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1069 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1071 "ult = RBAT (GBR+R0);",
1073 "WBAT (GBR + R0, ult);",
1076 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1077 "R[n] = (((R[n] >> 16) & 0xffff)",
1078 " | ((R[m] << 16) & 0xffff0000));",
1082 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1083 "divl(0,R[n],R[m]);",
1085 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1086 "divl(0,R[n],R[m]);",
1094 /* If this is disabled, the simulator speeds up by about 12% on a
1095 450 MHz PIII - 9% with ACE_FAST.
1096 Maybe we should have separate simulator loops? */
1098 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1101 "DSP_R (m) = RSWAT (R[n]) << 16;",
1102 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1104 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1106 "DSP_R (m) = RSWAT (R[n]) << 16;",
1107 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1109 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1111 "DSP_R (m) = RSWAT (R[n]) << 16;",
1112 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1115 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1117 "DSP_R (m) = RSWAT (R[n]) << 16;",
1118 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1121 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1124 "DSP_R (m) = RSWAT (R[n]);",
1126 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1128 "DSP_R (m) = RSWAT (R[n]);",
1130 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1132 "DSP_R (m) = RSWAT (R[n]);",
1135 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1137 "DSP_R (m) = RSWAT (R[n]);",
1140 { "n", "n", "<DSP_REG_M>,movs.w @-<REG_N>", "111101NNMMMM0001",
1143 "WWAT (R[n], DSP_R (m) >> 16);",
1145 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1147 "WWAT (R[n], DSP_R (m) >> 16);",
1149 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1151 "WWAT (R[n], DSP_R (m) >> 16);",
1154 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1156 "WWAT (R[n], DSP_R (m) >> 16);",
1159 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1162 "WWAT (R[n], SEXT (DSP_R (m)));",
1164 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1166 "WWAT (R[n], SEXT (DSP_R (m)));",
1168 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1170 "WWAT (R[n], SEXT (DSP_R (m)));",
1173 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1175 "WWAT (R[n], SEXT (DSP_R (m)));",
1178 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1181 "DSP_R (m) = RLAT (R[n]);",
1182 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1184 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1186 "DSP_R (m) = RLAT (R[n]);",
1187 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1189 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1191 "DSP_R (m) = RLAT (R[n]);",
1192 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1195 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1197 "DSP_R (m) = RLAT (R[n]);",
1198 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1201 { "n", "n", "<DSP_REG_M>,movs.l @-<REG_N>", "111101NNMMMM0011",
1204 "WLAT (R[n], DSP_R (m));",
1206 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1208 "WLAT (R[n], DSP_R (m));",
1210 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1212 "WLAT (R[n], DSP_R (m));",
1215 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1217 "WLAT (R[n], DSP_R (m));",
1220 { "n", "n", "<DSP_GRD_M>,movs.l @-<REG_N>", "111101NNGGGG0011",
1223 "WLAT (R[n], SEXT (DSP_R (m)));",
1225 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1227 "WLAT (R[n], SEXT (DSP_R (m)));",
1229 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1231 "WLAT (R[n], SEXT (DSP_R (m)));",
1234 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1236 "WLAT (R[n], SEXT (DSP_R (m)));",
1239 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1240 "DSP_R (m) = RSWAT (R[n]) << 16;",
1241 "iword &= 0xfd53; goto top;",
1243 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1244 "DSP_R (m) = RSWAT (R[n]) << 16;",
1245 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1246 "iword &= 0xfd53; goto top;",
1248 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1249 "DSP_R (m) = RSWAT (R[n]) << 16;",
1250 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1251 "iword &= 0xfd53; goto top;",
1253 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1254 "WWAT (R[n], DSP_R (m) >> 16);",
1255 "iword &= 0xfd53; goto top;",
1257 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1258 "WWAT (R[n], DSP_R (m) >> 16);",
1259 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1260 "iword &= 0xfd53; goto top;",
1262 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101000",
1263 "WWAT (R[n], DSP_R (m) >> 16);",
1264 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1265 "iword &= 0xfd53; goto top;",
1267 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1268 "DSP_R (m) = RSWAT (R[n]) << 16;",
1270 { "n", "n", "movy.w @<REG_x>+,<DSP_YY>", "111100yyYY000010",
1271 "DSP_R (m) = RSWAT (R[n]) << 16;",
1272 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1274 { "n", "n9","movy.w @<REG_x>+REG_9,<DSP_YY>", "111100yyYY000010",
1275 "DSP_R (m) = RSWAT (R[n]) << 16;",
1276 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1278 { "", "n", "movy.w <DSP_Aa>,@<REG_x>", "111100yyAA010001",
1279 "WWAT (R[n], DSP_R (m) >> 16);",
1281 { "n", "n", "movy.w <DSP_Aa>,@<REG_x>+", "111100yyAA010010",
1282 "WWAT (R[n], DSP_R (m) >> 16);",
1283 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1285 { "n", "n9", "movy.w <DSP_Aa>,@<REG_x>+REG_9", "111100yyAA010010",
1286 "WWAT (R[n], DSP_R (m) >> 16);",
1287 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1289 { "", "", "nopx nopy", "1111000000000000",
1292 { "", "", "ppi", "1111100000000000",
1293 "ppi_insn (RIAT (nip));",
1295 "iword &= 0xf7ff; goto top;",
1302 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1303 "int Sz = DSP_R (z) & 0xffff0000;",
1307 "else if (i >= 128 - 16)",
1308 " res = Sz >> 128 - i;",
1311 " RAISE_EXCEPTION (SIGILL);",
1314 "res &= 0xffff0000;",
1318 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1319 "int Sz = DSP_R (z);",
1320 "int Sz_grd = GET_DSP_GRD (z);",
1332 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1334 " res_grd = SEXT (res_grd);",
1335 " carry = res_grd & 1;",
1337 "else if (i >= 96)",
1342 " res_grd = SIGN32 (Sz_grd);",
1347 " res = Sz >> i | Sz_grd << 32 - i;",
1348 " res_grd = Sz_grd >> i;",
1350 " carry = Sz >> (i - 1) & 1;",
1354 " RAISE_EXCEPTION (SIGILL);",
1357 "COMPUTE_OVERFLOW;",
1358 "greater_equal = 0;",
1360 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1361 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1362 "if (res == 0x80000000)",
1363 " res = 0x7fffffff;",
1365 "DSP_GRD (g) = SIGN32 (res);",
1368 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1369 "int Sx = DSP_R (x);",
1370 "int Sx_grd = GET_DSP_GRD (x);",
1371 "int Sy = DSP_R (y);",
1372 "int Sy_grd = SIGN32 (Sy);",
1374 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1375 "if (res == 0x80000000)",
1376 " res = 0x7fffffff;",
1378 "DSP_GRD (g) = SIGN32 (res);",
1382 "carry = (unsigned) res > (unsigned) Sx;",
1383 "res_grd = Sx_grd - Sy_grd - carry;",
1384 "COMPUTE_OVERFLOW;",
1387 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1388 "int Sx = DSP_R (x);",
1389 "int Sx_grd = GET_DSP_GRD (x);",
1390 "int Sy = DSP_R (y);",
1391 "int Sy_grd = SIGN32 (Sy);",
1393 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1394 "if (res == 0x80000000)",
1395 " res = 0x7fffffff;",
1397 "DSP_GRD (g) = SIGN32 (res);",
1401 "carry = (unsigned) res < (unsigned) Sx;",
1402 "res_grd = Sx_grd + Sy_grd + carry;",
1403 "COMPUTE_OVERFLOW;",
1405 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1406 "int Sx = DSP_R (x);",
1407 "int Sx_grd = GET_DSP_GRD (x);",
1408 "int Sy = DSP_R (y);",
1409 "int Sy_grd = SIGN32 (Sy);",
1411 "res = Sx - Sy - (DSR & 1);",
1412 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1413 "res_grd = Sx_grd + Sy_grd + carry;",
1414 "COMPUTE_OVERFLOW;",
1417 "if (res || res_grd)\n",
1418 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1420 " DSR |= DSR_MASK_Z | overflow;\n",
1424 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1425 "int Sx = DSP_R (x);",
1426 "int Sx_grd = GET_DSP_GRD (x);",
1427 "int Sy = DSP_R (y);",
1428 "int Sy_grd = SIGN32 (Sy);",
1430 "res = Sx + Sy + (DSR & 1);",
1431 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1432 "res_grd = Sx_grd + Sy_grd + carry;",
1433 "COMPUTE_OVERFLOW;",
1436 "if (res || res_grd)\n",
1437 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1439 " DSR |= DSR_MASK_Z | overflow;\n",
1443 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1444 "int Sx = DSP_R (x);",
1445 "int Sx_grd = GET_DSP_GRD (x);",
1446 "int Sy = DSP_R (y);",
1447 "int Sy_grd = SIGN32 (Sy);",
1449 "z = 17; /* Ignore result. */",
1451 "carry = (unsigned) res > (unsigned) Sx;",
1452 "res_grd = Sx_grd - Sy_grd - carry;",
1453 "COMPUTE_OVERFLOW;",
1456 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1458 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1460 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1462 "res_grd = GET_DSP_GRD (x);",
1468 " carry = (res != 0); /* The manual has a bug here. */",
1469 " res_grd = -res_grd - carry;",
1471 "COMPUTE_OVERFLOW;",
1472 "/* ??? The re-computing of overflow after",
1473 " saturation processing is specific to pabs. */",
1474 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1477 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1478 "int Sx = DSP_R (x);",
1479 "int Sx_grd = GET_DSP_GRD (x);",
1481 "res = Sx + 0x8000;",
1482 "carry = (unsigned) res < (unsigned) Sx;",
1483 "res_grd = Sx_grd + carry;",
1484 "COMPUTE_OVERFLOW;",
1487 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1491 "greater_equal = DSR_MASK_G;",
1501 " res = 0x7fffffff;",
1504 " overflow = DSR_MASK_V;",
1505 " greater_equal = 0;",
1510 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1511 "int Sy = DSP_R (y);",
1512 "int Sy_grd = SIGN32 (Sy);",
1514 "res = Sy + 0x8000;",
1515 "carry = (unsigned) res < (unsigned) Sy;",
1516 "res_grd = Sy_grd + carry;",
1517 "COMPUTE_OVERFLOW;",
1520 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1521 "int Sx = DSP_R (x) & 0xffff0000;",
1522 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1526 "else if (Sy >= 128 - 16)",
1527 " res = Sx >> 128 - Sy;",
1530 " RAISE_EXCEPTION (SIGILL);",
1533 "goto cond_logical;",
1535 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1536 "int Sx = DSP_R (x);",
1537 "int Sx_grd = GET_DSP_GRD (x);",
1538 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1550 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1552 " res_grd = SEXT (res_grd);",
1553 " carry = res_grd & 1;",
1555 "else if (Sy >= 96)",
1560 " res_grd = SIGN32 (Sx_grd);",
1565 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1566 " res_grd = Sx_grd >> Sy;",
1568 " carry = Sx >> (Sy - 1) & 1;",
1572 " RAISE_EXCEPTION (SIGILL);",
1575 "COMPUTE_OVERFLOW;",
1576 "greater_equal = 0;",
1578 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1579 "int Sx = DSP_R (x);",
1580 "int Sx_grd = GET_DSP_GRD (x);",
1581 "int Sy = DSP_R (y);",
1582 "int Sy_grd = SIGN32 (Sy);",
1585 "carry = (unsigned) res > (unsigned) Sx;",
1586 "res_grd = Sx_grd - Sy_grd - carry;",
1587 "COMPUTE_OVERFLOW;",
1590 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1591 "int Sx = DSP_R (x);",
1592 "int Sx_grd = GET_DSP_GRD (x);",
1593 "int Sy = DSP_R (y);",
1594 "int Sy_grd = SIGN32 (Sy);",
1597 "carry = (unsigned) res < (unsigned) Sx;",
1598 "res_grd = Sx_grd + Sy_grd + carry;",
1599 "COMPUTE_OVERFLOW;",
1602 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1603 "res = DSP_R (x) & DSP_R (y);",
1605 "res &= 0xffff0000;",
1607 "if (iword & 0x200)\n",
1608 " goto assign_z;\n",
1612 "greater_equal = 0;",
1615 " DSR |= res >> 26 & DSR_MASK_N;\n",
1617 " DSR |= DSR_MASK_Z;\n",
1618 "goto assign_dc;\n",
1620 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1621 "res = DSP_R (x) ^ DSP_R (y);",
1622 "goto cond_logical;",
1624 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1625 "res = DSP_R (x) | DSP_R (y);",
1626 "goto cond_logical;",
1628 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1629 "int Sx = DSP_R (x);",
1630 "int Sx_grd = GET_DSP_GRD (x);",
1632 "res = Sx - 0x10000;",
1633 "carry = res > Sx;",
1634 "res_grd = Sx_grd - carry;",
1635 "COMPUTE_OVERFLOW;",
1637 "res &= 0xffff0000;",
1639 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1640 "int Sx = DSP_R (x);",
1641 "int Sx_grd = GET_DSP_GRD (x);",
1643 "res = Sx + 0x10000;",
1644 "carry = res < Sx;",
1645 "res_grd = Sx_grd + carry;",
1646 "COMPUTE_OVERFLOW;",
1648 "res &= 0xffff0000;",
1650 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1651 "int Sy = DSP_R (y);",
1652 "int Sy_grd = SIGN32 (Sy);",
1654 "res = Sy - 0x10000;",
1655 "carry = res > Sy;",
1656 "res_grd = Sy_grd - carry;",
1657 "COMPUTE_OVERFLOW;",
1659 "res &= 0xffff0000;",
1661 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1662 "int Sy = DSP_R (y);",
1663 "int Sy_grd = SIGN32 (Sy);",
1665 "res = Sy + 0x10000;",
1666 "carry = res < Sy;",
1667 "res_grd = Sy_grd + carry;",
1668 "COMPUTE_OVERFLOW;",
1670 "res &= 0xffff0000;",
1672 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1677 "greater_equal = 1;",
1679 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1680 "unsigned Sx = DSP_R (x);",
1681 "int Sx_grd = GET_DSP_GRD (x);",
1686 " Sx_grd = ~Sx_grd;",
1700 " if (Sx & ~0 << i)",
1708 "res_grd = SIGN32 (res);",
1713 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1714 "unsigned Sy = DSP_R (y);",
1723 " if (Sy & ~0 << i)",
1731 "res_grd = SIGN32 (res);",
1736 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1737 "int Sx = DSP_R (x);",
1738 "int Sx_grd = GET_DSP_GRD (x);",
1741 "carry = res != 0;",
1742 "res_grd = 0 - Sx_grd - carry;",
1743 "COMPUTE_OVERFLOW;",
1746 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1748 "res_grd = GET_DSP_GRD (x);",
1750 "COMPUTE_OVERFLOW;",
1753 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1754 "int Sy = DSP_R (y);",
1755 "int Sy_grd = SIGN32 (Sy);",
1758 "carry = res != 0;",
1759 "res_grd = 0 - Sy_grd - carry;",
1760 "COMPUTE_OVERFLOW;",
1763 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1765 "res_grd = SIGN32 (res);",
1767 "COMPUTE_OVERFLOW;",
1770 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1772 "res_grd = SIGN32 (res);",
1775 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1777 "res_grd = SIGN32 (res);",
1780 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1781 "if (0xa05f >> z & 1)",
1782 " RAISE_EXCEPTION (SIGILL);",
1784 " MACH = DSP_R (z);",
1787 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1788 "if (0xa05f >> z & 1)",
1789 " RAISE_EXCEPTION (SIGILL);",
1791 " MACL = DSP_R (z) = res;",
1797 /* Tables of things to put into enums for sh-opc.h */
1798 static char *nibble_type_list[] =
1833 char *arg_type_list[] =
1867 make_enum_list (name, s)
1872 printf ("typedef enum {\n");
1875 printf ("\t%s,\n", *s);
1879 printf ("} %s;\n", name);
1891 memcpy (bufa, a->code, 4);
1892 memcpy (bufa + 4, a->code + 12, 4);
1895 memcpy (bufb, b->code, 4);
1896 memcpy (bufb + 4, b->code + 12, 4);
1898 diff = strcmp (bufa, bufb);
1899 /* Stabilize the sort, so that later entries can override more general
1900 preceding entries. */
1901 return diff ? diff : a - b;
1915 qsort (tab, len, sizeof (*p), qfunc);
1923 for (p = tab; p->name; p++)
1925 printf ("%s %-30s\n", p->code, p->name);
1931 /* Convert a string of 4 binary digits into an int */
1951 static unsigned char table[1 << 16];
1953 /* Take an opcode expand all varying fields in it out and fill all the
1954 right entries in 'table' with the opcode index*/
1957 expand_opcode (shift, val, i, s)
1979 val |= bton (s) << shift;
1980 if (s[2] == '0' || s[2] == '1')
1981 expand_opcode (shift - 4, val, i, s + 4);
1982 else if (s[2] == 'N')
1983 for (j = 0; j < 4; j++)
1984 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1985 else if (s[2] == 'x')
1986 for (j = 0; j < 4; j += 2)
1987 for (m = 0; m < 32; m++)
1989 /* Ignore illegal nopy */
1990 if ((m & 7) == 0 && m != 0)
1992 mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
1993 expand_opcode (shift - 4, val | mv | (j << shift), i,
1996 else if (s[2] == 'y')
1997 for (j = 0; j < 2; j++)
1998 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2003 for (j = 0; j < 16; j++)
2005 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2010 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2011 for (j = 5; j < 16; j++)
2013 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2017 for (j = 13; j <= 15; j +=2)
2018 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2021 /* System registers mach, macl, pr: */
2022 for (j = 0; j < 3; j++)
2023 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2024 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2025 for (j = 5; j < 12; j++)
2026 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2030 val |= bton (s) << shift;
2031 for (j = 0; j < 16; j += 8)
2032 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2036 val |= bton (s) << shift;
2037 for (j = 0; j < 8; j += 4)
2038 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2042 for (j = 0; j < (1 << (shift + 4)); j++)
2050 /* Print the jump table used to index an opcode into a switch
2054 dumptable (name, size, start)
2064 printf ("unsigned char %s[%d]={\n", name, size);
2065 while (i < start + size)
2069 printf ("/* 0x%x */\n", i);
2076 printf ("%2d", table[i + j + k]);
2095 static int index = 1;
2098 for (; p->name; p++)
2101 expand_opcode (12, 0, p->index, p->code);
2105 /* Table already contais all the switch case tags for 16-bit opcode double
2106 data transfer (ddt) insns, and the switch case tag for processing parallel
2107 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2108 latter tag to represent all combinations of ppi with ddt. */
2114 for (i = 0xf000; i < 0xf400; i++)
2116 table[i + 0x800] = table[0xf800];
2123 for (; p->name; p++)
2132 printf (" /* %s %s */\n", p->name, p->code);
2133 printf (" case %d: \n", p->index);
2148 printf (" int n = (iword >>8) & 0xf;\n");
2153 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2157 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2162 printf (" int n = ((iword >> 8) & 1) + 4;\n");
2171 printf (" int m = (iword >>4) & 0xf;\n");
2175 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2179 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2183 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2187 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2192 printf (" int i = (iword & 0x");
2227 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2228 sextbit - 1, sextbit - 1);
2232 printf (" TB(m,n);\n");
2234 printf (" TL(m);\n");
2236 printf (" TL(n);\n");
2241 for (r = p->refs; *r; r++)
2243 if (*r == '0') printf(" CREF(0);\n");
2244 if (*r == '8') printf(" CREF(8);\n");
2245 if (*r == '9') printf(" CREF(9);\n");
2246 if (*r == 'n') printf(" CREF(n);\n");
2247 if (*r == 'm') printf(" CREF(m);\n");
2252 for (j = 0; j < MAX_NR_STUFF; j++)
2256 printf (" %s\n", p->stuff[j]);
2264 for (r = p->defs; *r; r++)
2266 if (*r == '0') printf(" CDEF(0);\n");
2267 if (*r == 'n') printf(" CDEF(n);\n");
2268 if (*r == 'm') printf(" CDEF(m);\n");
2272 printf (" break;\n");
2281 printf (" switch (jump_table[iword]) {\n");
2283 gensim_caselist (tab);
2284 gensim_caselist (movsxy_tab);
2286 printf (" default:\n");
2288 printf (" RAISE_EXCEPTION (SIGILL);\n");
2299 for (p = tab; p->name; p++)
2302 printf ("#define OPC_");
2306 if (isalpha(*s)) printf("%c", *s);
2307 if (*s == ' ') printf("_");
2308 if (*s == '@') printf("ind_");
2309 if (*s == ',') printf("_");
2312 printf(" %d\n",p->index);
2316 static int ppi_index;
2318 /* Take an ppi code, expand all varying fields in it and fill all the
2319 right entries in 'table' with the opcode index. */
2322 expand_ppi_code (val, i, s)
2333 /* The last eight bits are disregarded for the switch table. */
2351 expand_ppi_code (val, i, s);
2358 expand_ppi_code (val, ppi_index++, s);
2360 expand_ppi_code (val, i, s);
2373 for (p = ppi_tab; p->name; p++)
2375 p->index = ppi_index++;
2376 expand_ppi_code (0, p->index, p->code);
2385 printf ("#define DSR_MASK_G 0x80\n");
2386 printf ("#define DSR_MASK_Z 0x40\n");
2387 printf ("#define DSR_MASK_N 0x20\n");
2388 printf ("#define DSR_MASK_V 0x10\n");
2390 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2391 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2392 printf (" if (overflow && S) \\\n");
2394 printf (" if (res_grd & 0x80) \\\n");
2396 printf (" res = 0x80000000; \\\n");
2397 printf (" res_grd |= 0xff; \\\n");
2399 printf (" else \\\n");
2401 printf (" res = 0x7fffffff; \\\n");
2402 printf (" res_grd &= ~0xff; \\\n");
2404 printf (" overflow = 0; \\\n");
2406 printf ("} while (0)\n");
2408 printf ("#define ADD_SUB_GE \\\n");
2409 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2411 printf ("static void\n");
2412 printf ("ppi_insn (iword)\n");
2413 printf (" int iword;\n");
2415 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2416 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2417 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2418 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2419 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2420 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2422 printf (" int z;\n");
2423 printf (" int res, res_grd;\n");
2424 printf (" int carry, overflow, greater_equal;\n");
2426 printf (" switch (ppi_table[iword >> 8]) {\n");
2428 for (; p->name; p++)
2436 printf (" /* %s %s */\n", p->name, p->code);
2437 printf (" case %d: \n", p->index);
2440 for (shift = 16; *s; )
2445 printf (" int i = (iword >> 4) & 0x7f;\n");
2455 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2461 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2462 printf ("\tbreak;\n");
2464 printf (" case %d: \n", p->index + 1);
2476 printf (" z = iword & 0xf;\n");
2484 else if (havedecl == 2)
2486 for (j = 0; j < MAX_NR_STUFF; j++)
2491 (havedecl == 2 ? " " : ""),
2499 printf (" if (iword & 0x200)\n");
2500 printf (" goto assign_z;\n");
2502 printf (" break;\n");
2506 printf (" default:\n");
2508 printf (" RAISE_EXCEPTION (SIGILL);\n");
2509 printf (" return;\n");
2512 printf (" DSR &= ~0xf1;\n");
2513 printf (" if (res || res_grd)\n");
2514 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2516 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2517 printf (" assign_dc:\n");
2518 printf (" switch (DSR >> 1 & 7)\n");
2520 printf (" case 0: /* Carry Mode */\n");
2521 printf (" DSR |= carry;\n");
2522 printf (" case 1: /* Negative Value Mode */\n");
2523 printf (" DSR |= res_grd >> 7 & 1;\n");
2524 printf (" case 2: /* Zero Value Mode */\n");
2525 printf (" DSR |= DSR >> 6 & 1;\n");
2526 printf (" case 3: /* Overflow mode\n");
2527 printf (" DSR |= overflow >> 4;\n");
2528 printf (" case 4: /* Signed Greater Than Mode */\n");
2529 printf (" DSR |= DSR >> 7 & 1;\n");
2530 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2531 printf (" DSR |= greater_equal >> 7;\n");
2533 printf (" assign_z:\n");
2534 printf (" if (0xa05f >> z & 1)\n");
2536 printf (" RAISE_EXCEPTION (SIGILL);\n");
2537 printf (" return;\n");
2539 printf (" DSP_R (z) = res;\n");
2540 printf (" DSP_GRD (z) = res_grd;\n");
2549 /* verify the table before anything else */
2552 for (p = tab; p->name; p++)
2554 /* check that the code field contains 16 bits */
2555 if (strlen (p->code) != 16)
2557 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2558 p->code, strlen (p->code), p->name);
2564 /* now generate the requested data */
2567 if (strcmp (av[1], "-t") == 0)
2571 else if (strcmp (av[1], "-d") == 0)
2575 else if (strcmp (av[1], "-s") == 0)
2578 dumptable ("sh_jump_table", 1 << 16, 0);
2580 memset (table, 0, sizeof table);
2581 filltable (movsxy_tab);
2583 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2585 memset (table, 0, sizeof table);
2587 dumptable ("ppi_table", 1 << 8, 0);
2589 else if (strcmp (av[1], "-x") == 0)
2592 filltable (movsxy_tab);
2595 else if (strcmp (av[1], "-p") == 0)
2602 fprintf (stderr, "Opcode table generation no longer supported.\n");