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 "trap (255, R0, PC, memory, maskl, maskw, endianw);",
584 "/* FIXME: mac.l support */",
587 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
588 "macw(R0,memory,n,m,endianw);",
591 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
594 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
598 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
600 "R0 = RSBAT (i + GBR);",
603 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
605 "R0 = RSBAT (i + R[m]);",
608 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
610 "R[n] = RSBAT (R0 + R[m]);",
613 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
615 "R[n] = RSBAT (R[m]);",
619 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
621 "WBAT (R[n], R[m]);",
623 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
625 "WBAT (i + GBR, R0);",
627 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
629 "WBAT (i + R[m], R0);",
631 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
633 "WBAT (R[n] + R0, R[m]);",
635 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
638 "WBAT (R[n], R[m]);",
640 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
642 "R[n] = RSBAT (R[m]);",
646 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
648 "R0 = RLAT (i + GBR);",
651 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
653 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
656 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
658 "R[n] = RLAT (i + R[m]);",
661 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
663 "R[n] = RLAT (R0 + R[m]);",
666 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
668 "R[n] = RLAT (R[m]);",
672 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
674 "R[n] = RLAT (R[m]);",
677 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
679 "WLAT (i + GBR, R0);",
681 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
683 "WLAT (i + R[n], R[m]);",
685 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
687 "WLAT (R0 + R[n], R[m]);",
689 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
692 "WLAT (R[n], R[m]);",
694 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
696 "WLAT (R[n], R[m]);",
699 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
701 "R0 = RSWAT (i + GBR);",
704 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
706 "R[n] = RSWAT (PH2T (PC + 4 + i));",
709 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
711 "R0 = RSWAT (i + R[m]);",
714 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
716 "R[n] = RSWAT (R0 + R[m]);",
719 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
721 "R[n] = RSWAT (R[m]);",
725 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
727 "R[n] = RSWAT (R[m]);",
730 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
732 "WWAT (i + GBR, R0);",
734 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
736 "WWAT (i + R[m], R0);",
738 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
740 "WWAT (R0 + R[n], R[m]);",
742 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
745 "WWAT (R[n], R[m]);",
747 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
749 "WWAT (R[n], R[m]);",
752 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
753 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
756 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
757 "/* We don't simulate cache, so this insn is identical to mov. */",
759 "WLAT (R[n], R[0]);",
762 { "n", "", "movt <REG_N>", "0000nnnn00101001",
766 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
767 "MACL = ((int)R[n]) * ((int)R[m]);",
770 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
771 "MACL = R[n] * R[m];",
775 /* muls.w - see muls */
776 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
777 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
780 /* mulu.w - see mulu */
781 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
782 "MACL = (((unsigned int)(unsigned short)R[n])",
783 " * ((unsigned int)(unsigned short)R[m]));",
786 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
790 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
792 "SET_SR_T (ult > 0);",
793 "R[n] = ult - R[m];",
794 "SET_SR_T (T || (R[n] > ult));",
797 { "", "", "nop", "0000000000001001",
801 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
805 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
806 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
807 "/* FIXME: Cache not implemented */",
810 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
811 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
812 "/* FIXME: Cache not implemented */",
815 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
816 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
817 "/* FIXME: Cache not implemented */",
820 { "0", "", "or #<imm>,R0", "11001011i8*1....",
823 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
826 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
828 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
831 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
832 "/* Except for the effect on the cache - which is not simulated -",
833 " this is like a nop. */",
836 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
838 "R[n] = (R[n] << 1) | T;",
842 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
844 "R[n] = (UR[n] >> 1) | (T << 31);",
848 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
849 "SET_SR_T (R[n] < 0);",
854 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
855 "SET_SR_T (R[n] & 1);",
856 "R[n] = UR[n] >> 1;",
857 "R[n] |= (T << 31);",
860 { "", "", "rte", "0000000000101011",
864 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
866 "SET_SR (RLAT (R[15]) & 0x3f3);",
868 "Delay_Slot (PC + 2);",
871 "SET_NIP (PT2H (SPC));",
873 "Delay_Slot (PC + 2);",
877 { "", "", "rts", "0000000000001011",
878 "SET_NIP (PT2H (PR));",
880 "Delay_Slot (PC + 2);",
884 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
887 { "", "", "setrc #<imm>", "10000010i8*1....",
888 /* It would be more realistic to let loop_start point to some static
889 memory that contains an illegal opcode and then give a bus error when
890 the loop is eventually encountered, but it seems not only simpler,
891 but also more debugging-friendly to just catch the failure here. */
892 "if (BUSERROR (RS | RE, maskw))",
893 " RAISE_EXCEPTION (SIGILL);",
896 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
897 " CHECK_INSN_PTR (insn_ptr);",
901 { "", "", "sets", "0000000001011000",
905 { "", "", "sett", "0000000000011000",
909 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
910 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
913 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
914 "SET_SR_T (R[n] < 0);",
918 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
919 "SET_SR_T (R[n] & 1);",
923 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
924 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
927 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
928 "SET_SR_T (R[n] < 0);",
932 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
935 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
938 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
942 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
943 "SET_SR_T (R[n] & 1);",
944 "R[n] = UR[n] >> 1;",
947 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
948 "R[n] = UR[n] >> 2;",
950 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
951 "R[n] = UR[n] >> 8;",
953 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
954 "R[n] = UR[n] >> 16;",
957 { "", "", "sleep", "0000000000011011",
958 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
961 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
966 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
969 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
973 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
976 "WLAT (R[n], CREG (m));",
979 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
984 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
991 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
994 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
997 "WLAT (R[n], SREG (m));",
1000 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1004 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1006 "SET_SR_T (ult > R[n]);",
1007 "R[n] = ult - R[m];",
1008 "SET_SR_T (T || (R[n] > ult));",
1011 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1012 "ult = R[n] - R[m];",
1013 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1017 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1018 "R[n] = ((R[m] & 0xffff0000)",
1019 " | ((R[m] << 8) & 0xff00)",
1020 " | ((R[m] >> 8) & 0x00ff));",
1022 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1023 "R[n] = (((R[m] << 16) & 0xffff0000)",
1024 " | ((R[m] >> 16) & 0x00ffff));",
1027 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1029 "ult = RBAT(R[n]);",
1030 "SET_SR_T (ult == 0);",
1031 "WBAT(R[n],ult|0x80);",
1034 { "0", "", "trapa #<imm>", "11000011i8*1....",
1035 "long imm = 0xff & i;",
1036 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1037 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1042 " WLAT (R[15], GET_SR());",
1044 " WLAT (R[15], PH2T (PC + 2));",
1046 "else if (!SR_BL) {",
1048 " SPC = PH2T (PC + 2);",
1049 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1050 " /* FIXME: EXPEVT = 0x00000160; */",
1052 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1056 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1057 "SET_SR_T ((R[n] & R[m]) == 0);",
1059 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1060 "SET_SR_T ((R0 & i) == 0);",
1062 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1064 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1067 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1070 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1073 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1075 "ult = RBAT (GBR+R0);",
1077 "WBAT (GBR + R0, ult);",
1080 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1081 "R[n] = (((R[n] >> 16) & 0xffff)",
1082 " | ((R[m] << 16) & 0xffff0000));",
1086 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1087 "divl(0,R[n],R[m]);",
1089 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1090 "divl(0,R[n],R[m]);",
1098 /* If this is disabled, the simulator speeds up by about 12% on a
1099 450 MHz PIII - 9% with ACE_FAST.
1100 Maybe we should have separate simulator loops? */
1102 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1105 "DSP_R (m) = RSWAT (R[n]) << 16;",
1106 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1108 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1110 "DSP_R (m) = RSWAT (R[n]) << 16;",
1111 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1113 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1115 "DSP_R (m) = RSWAT (R[n]) << 16;",
1116 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1119 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1121 "DSP_R (m) = RSWAT (R[n]) << 16;",
1122 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1125 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1128 "DSP_R (m) = RSWAT (R[n]);",
1130 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1132 "DSP_R (m) = RSWAT (R[n]);",
1134 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1136 "DSP_R (m) = RSWAT (R[n]);",
1139 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1141 "DSP_R (m) = RSWAT (R[n]);",
1144 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1147 "WWAT (R[n], DSP_R (m) >> 16);",
1149 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1151 "WWAT (R[n], DSP_R (m) >> 16);",
1153 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1155 "WWAT (R[n], DSP_R (m) >> 16);",
1158 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1160 "WWAT (R[n], DSP_R (m) >> 16);",
1163 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1166 "WWAT (R[n], SEXT (DSP_R (m)));",
1168 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1170 "WWAT (R[n], SEXT (DSP_R (m)));",
1172 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1174 "WWAT (R[n], SEXT (DSP_R (m)));",
1177 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1179 "WWAT (R[n], SEXT (DSP_R (m)));",
1182 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1185 "DSP_R (m) = RLAT (R[n]);",
1186 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1188 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1190 "DSP_R (m) = RLAT (R[n]);",
1191 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1193 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1195 "DSP_R (m) = RLAT (R[n]);",
1196 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1199 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1201 "DSP_R (m) = RLAT (R[n]);",
1202 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1205 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1208 "WLAT (R[n], DSP_R (m));",
1210 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1212 "WLAT (R[n], DSP_R (m));",
1214 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1216 "WLAT (R[n], DSP_R (m));",
1219 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1221 "WLAT (R[n], DSP_R (m));",
1224 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1227 "WLAT (R[n], SEXT (DSP_R (m)));",
1229 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1231 "WLAT (R[n], SEXT (DSP_R (m)));",
1233 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1235 "WLAT (R[n], SEXT (DSP_R (m)));",
1238 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1240 "WLAT (R[n], SEXT (DSP_R (m)));",
1243 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1244 "DSP_R (m) = RSWAT (R[n]) << 16;",
1245 "iword &= 0xfd53; goto top;",
1247 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1248 "DSP_R (m) = RSWAT (R[n]) << 16;",
1249 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1250 "iword &= 0xfd53; goto top;",
1252 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001100",
1253 "DSP_R (m) = RSWAT (R[n]) << 16;",
1254 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1255 "iword &= 0xfd53; goto top;",
1257 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1258 "WWAT (R[n], DSP_R (m) >> 16);",
1259 "iword &= 0xfd53; goto top;",
1261 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1262 "WWAT (R[n], DSP_R (m) >> 16);",
1263 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1264 "iword &= 0xfd53; goto top;",
1266 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
1267 "WWAT (R[n], DSP_R (m) >> 16);",
1268 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1269 "iword &= 0xfd53; goto top;",
1271 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1272 "DSP_R (m) = RSWAT (R[n]) << 16;",
1274 { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
1275 "DSP_R (m) = RSWAT (R[n]) << 16;",
1276 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1278 { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000011",
1279 "DSP_R (m) = RSWAT (R[n]) << 16;",
1280 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1282 { "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
1283 "WWAT (R[n], DSP_R (m) >> 16);",
1285 { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
1286 "WWAT (R[n], DSP_R (m) >> 16);",
1287 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1289 { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010011",
1290 "WWAT (R[n], DSP_R (m) >> 16);",
1291 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1293 { "", "", "nopx nopy", "1111000000000000",
1296 { "", "", "ppi", "1111100000000000",
1297 "ppi_insn (RIAT (nip));",
1299 "iword &= 0xf7ff; goto top;",
1306 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1307 "int Sz = DSP_R (z) & 0xffff0000;",
1311 "else if (i >= 128 - 16)",
1312 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1315 " RAISE_EXCEPTION (SIGILL);",
1318 "res &= 0xffff0000;",
1322 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1323 "int Sz = DSP_R (z);",
1324 "int Sz_grd = GET_DSP_GRD (z);",
1336 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1338 " res_grd = SEXT (res_grd);",
1339 " carry = res_grd & 1;",
1341 "else if (i >= 96)",
1346 " res_grd = SIGN32 (Sz_grd);",
1351 " res = Sz >> i | Sz_grd << 32 - i;",
1352 " res_grd = Sz_grd >> i;",
1354 " carry = Sz >> (i - 1) & 1;",
1358 " RAISE_EXCEPTION (SIGILL);",
1361 "COMPUTE_OVERFLOW;",
1362 "greater_equal = 0;",
1364 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1365 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1366 "if (res == 0x80000000)",
1367 " res = 0x7fffffff;",
1369 "DSP_GRD (g) = SIGN32 (res);",
1372 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1373 "int Sx = DSP_R (x);",
1374 "int Sx_grd = GET_DSP_GRD (x);",
1375 "int Sy = DSP_R (y);",
1376 "int Sy_grd = SIGN32 (Sy);",
1378 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1379 "if (res == 0x80000000)",
1380 " res = 0x7fffffff;",
1382 "DSP_GRD (g) = SIGN32 (res);",
1386 "carry = (unsigned) res > (unsigned) Sx;",
1387 "res_grd = Sx_grd - Sy_grd - carry;",
1388 "COMPUTE_OVERFLOW;",
1391 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1392 "int Sx = DSP_R (x);",
1393 "int Sx_grd = GET_DSP_GRD (x);",
1394 "int Sy = DSP_R (y);",
1395 "int Sy_grd = SIGN32 (Sy);",
1397 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1398 "if (res == 0x80000000)",
1399 " res = 0x7fffffff;",
1401 "DSP_GRD (g) = SIGN32 (res);",
1405 "carry = (unsigned) res < (unsigned) Sx;",
1406 "res_grd = Sx_grd + Sy_grd + carry;",
1407 "COMPUTE_OVERFLOW;",
1409 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1410 "int Sx = DSP_R (x);",
1411 "int Sx_grd = GET_DSP_GRD (x);",
1412 "int Sy = DSP_R (y);",
1413 "int Sy_grd = SIGN32 (Sy);",
1415 "res = Sx - Sy - (DSR & 1);",
1416 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1417 "res_grd = Sx_grd + Sy_grd + carry;",
1418 "COMPUTE_OVERFLOW;",
1421 "if (res || res_grd)\n",
1422 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1424 " DSR |= DSR_MASK_Z | overflow;\n",
1428 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1429 "int Sx = DSP_R (x);",
1430 "int Sx_grd = GET_DSP_GRD (x);",
1431 "int Sy = DSP_R (y);",
1432 "int Sy_grd = SIGN32 (Sy);",
1434 "res = Sx + Sy + (DSR & 1);",
1435 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1436 "res_grd = Sx_grd + Sy_grd + carry;",
1437 "COMPUTE_OVERFLOW;",
1440 "if (res || res_grd)\n",
1441 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1443 " DSR |= DSR_MASK_Z | overflow;\n",
1447 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1448 "int Sx = DSP_R (x);",
1449 "int Sx_grd = GET_DSP_GRD (x);",
1450 "int Sy = DSP_R (y);",
1451 "int Sy_grd = SIGN32 (Sy);",
1453 "z = 17; /* Ignore result. */",
1455 "carry = (unsigned) res > (unsigned) Sx;",
1456 "res_grd = Sx_grd - Sy_grd - carry;",
1457 "COMPUTE_OVERFLOW;",
1460 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1462 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1464 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1466 "res_grd = GET_DSP_GRD (x);",
1472 " carry = (res != 0); /* The manual has a bug here. */",
1473 " res_grd = -res_grd - carry;",
1475 "COMPUTE_OVERFLOW;",
1476 "/* ??? The re-computing of overflow after",
1477 " saturation processing is specific to pabs. */",
1478 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1481 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1482 "int Sx = DSP_R (x);",
1483 "int Sx_grd = GET_DSP_GRD (x);",
1485 "res = (Sx + 0x8000) & 0xffff0000;",
1486 "carry = (unsigned) res < (unsigned) Sx;",
1487 "res_grd = Sx_grd + carry;",
1488 "COMPUTE_OVERFLOW;",
1491 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1495 "greater_equal = DSR_MASK_G;",
1505 " res = 0x7fffffff;",
1508 " overflow = DSR_MASK_V;",
1509 " greater_equal = 0;",
1514 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1515 "int Sy = DSP_R (y);",
1516 "int Sy_grd = SIGN32 (Sy);",
1518 "res = (Sy + 0x8000) & 0xffff0000;",
1519 "carry = (unsigned) res < (unsigned) Sy;",
1520 "res_grd = Sy_grd + carry;",
1521 "COMPUTE_OVERFLOW;",
1524 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1525 "int Sx = DSP_R (x) & 0xffff0000;",
1526 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1530 "else if (Sy >= 128 - 16)",
1531 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
1534 " RAISE_EXCEPTION (SIGILL);",
1537 "goto cond_logical;",
1539 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1540 "int Sx = DSP_R (x);",
1541 "int Sx_grd = GET_DSP_GRD (x);",
1542 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1554 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1556 " res_grd = SEXT (res_grd);",
1557 " carry = res_grd & 1;",
1559 "else if (Sy >= 96)",
1564 " res_grd = SIGN32 (Sx_grd);",
1569 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1570 " res_grd = Sx_grd >> Sy;",
1572 " carry = Sx >> (Sy - 1) & 1;",
1576 " RAISE_EXCEPTION (SIGILL);",
1579 "COMPUTE_OVERFLOW;",
1580 "greater_equal = 0;",
1582 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1583 "int Sx = DSP_R (x);",
1584 "int Sx_grd = GET_DSP_GRD (x);",
1585 "int Sy = DSP_R (y);",
1586 "int Sy_grd = SIGN32 (Sy);",
1589 "carry = (unsigned) res > (unsigned) Sx;",
1590 "res_grd = Sx_grd - Sy_grd - carry;",
1591 "COMPUTE_OVERFLOW;",
1594 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1595 "int Sx = DSP_R (x);",
1596 "int Sx_grd = GET_DSP_GRD (x);",
1597 "int Sy = DSP_R (y);",
1598 "int Sy_grd = SIGN32 (Sy);",
1601 "carry = (unsigned) res < (unsigned) Sx;",
1602 "res_grd = Sx_grd + Sy_grd + carry;",
1603 "COMPUTE_OVERFLOW;",
1606 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1607 "res = DSP_R (x) & DSP_R (y);",
1609 "res &= 0xffff0000;",
1611 "if (iword & 0x200)\n",
1612 " goto assign_z;\n",
1616 "greater_equal = 0;",
1619 " DSR |= res >> 26 & DSR_MASK_N;\n",
1621 " DSR |= DSR_MASK_Z;\n",
1622 "goto assign_dc;\n",
1624 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1625 "res = DSP_R (x) ^ DSP_R (y);",
1626 "goto cond_logical;",
1628 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1629 "res = DSP_R (x) | DSP_R (y);",
1630 "goto cond_logical;",
1632 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1633 "int Sx = DSP_R (x);",
1634 "int Sx_grd = GET_DSP_GRD (x);",
1636 "res = Sx - 0x10000;",
1637 "carry = res > Sx;",
1638 "res_grd = Sx_grd - carry;",
1639 "COMPUTE_OVERFLOW;",
1641 "res &= 0xffff0000;",
1643 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..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) pdec Sy,Dz", "101010cc..yyzzzz",
1655 "int Sy = DSP_R (y);",
1656 "int Sy_grd = SIGN32 (Sy);",
1658 "res = Sy - 0x10000;",
1659 "carry = res > Sy;",
1660 "res_grd = Sy_grd - carry;",
1661 "COMPUTE_OVERFLOW;",
1663 "res &= 0xffff0000;",
1665 { "","", "(if cc) pinc Sy,Dz", "101110cc..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) pclr Dz", "100011cc....zzzz",
1681 "greater_equal = 1;",
1683 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1684 "unsigned Sx = DSP_R (x);",
1685 "int Sx_grd = GET_DSP_GRD (x);",
1690 " Sx_grd = ~Sx_grd;",
1704 " if (Sx & ~0 << i)",
1712 "res_grd = SIGN32 (res);",
1717 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1718 "unsigned Sy = DSP_R (y);",
1727 " if (Sy & ~0 << i)",
1735 "res_grd = SIGN32 (res);",
1740 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1741 "int Sx = DSP_R (x);",
1742 "int Sx_grd = GET_DSP_GRD (x);",
1745 "carry = res != 0;",
1746 "res_grd = 0 - Sx_grd - carry;",
1747 "COMPUTE_OVERFLOW;",
1750 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1752 "res_grd = GET_DSP_GRD (x);",
1754 "COMPUTE_OVERFLOW;",
1757 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1758 "int Sy = DSP_R (y);",
1759 "int Sy_grd = SIGN32 (Sy);",
1762 "carry = res != 0;",
1763 "res_grd = 0 - Sy_grd - carry;",
1764 "COMPUTE_OVERFLOW;",
1767 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1769 "res_grd = SIGN32 (res);",
1771 "COMPUTE_OVERFLOW;",
1774 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1776 "res_grd = SIGN32 (res);",
1779 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1781 "res_grd = SIGN32 (res);",
1784 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1785 "if (0xa05f >> z & 1)",
1786 " RAISE_EXCEPTION (SIGILL);",
1788 " MACH = DSP_R (z);",
1791 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1792 "if (0xa05f >> z & 1)",
1793 " RAISE_EXCEPTION (SIGILL);",
1795 " MACL = DSP_R (z) = res;",
1801 /* Tables of things to put into enums for sh-opc.h */
1802 static char *nibble_type_list
[] =
1837 char *arg_type_list
[] =
1871 make_enum_list (name
, s
)
1876 printf ("typedef enum {\n");
1879 printf ("\t%s,\n", *s
);
1883 printf ("} %s;\n", name
);
1895 memcpy (bufa
, a
->code
, 4);
1896 memcpy (bufa
+ 4, a
->code
+ 12, 4);
1899 memcpy (bufb
, b
->code
, 4);
1900 memcpy (bufb
+ 4, b
->code
+ 12, 4);
1902 diff
= strcmp (bufa
, bufb
);
1903 /* Stabilize the sort, so that later entries can override more general
1904 preceding entries. */
1905 return diff
? diff
: a
- b
;
1919 qsort (tab
, len
, sizeof (*p
), qfunc
);
1927 for (p
= tab
; p
->name
; p
++)
1929 printf ("%s %-30s\n", p
->code
, p
->name
);
1935 /* Convert a string of 4 binary digits into an int */
1955 static unsigned char table
[1 << 16];
1957 /* Take an opcode expand all varying fields in it out and fill all the
1958 right entries in 'table' with the opcode index*/
1961 expand_opcode (shift
, val
, i
, s
)
1983 val
|= bton (s
) << shift
;
1984 if (s
[2] == '0' || s
[2] == '1')
1985 expand_opcode (shift
- 4, val
, i
, s
+ 4);
1986 else if (s
[2] == 'N')
1987 for (j
= 0; j
< 4; j
++)
1988 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
1989 else if (s
[2] == 'x')
1990 for (j
= 0; j
< 4; j
+= 2)
1991 for (m
= 0; m
< 32; m
++)
1993 /* Ignore illegal nopy */
1994 if ((m
& 7) == 0 && m
!= 0)
1996 mv
= m
& 3 | (m
& 4) << 2 | (m
& 8) << 3 | (m
& 16) << 4;
1997 expand_opcode (shift
- 4, val
| mv
| (j
<< shift
), i
,
2000 else if (s
[2] == 'y')
2001 for (j
= 0; j
< 2; j
++)
2002 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2007 for (j
= 0; j
< 16; j
++)
2009 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2014 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2015 for (j
= 5; j
< 16; j
++)
2017 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2021 for (j
= 13; j
<= 15; j
+=2)
2022 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2025 /* System registers mach, macl, pr: */
2026 for (j
= 0; j
< 3; j
++)
2027 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2028 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2029 for (j
= 5; j
< 12; j
++)
2030 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2034 val
|= bton (s
) << shift
;
2035 for (j
= 0; j
< 16; j
+= 8)
2036 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2040 val
|= bton (s
) << shift
;
2041 for (j
= 0; j
< 8; j
+= 4)
2042 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2046 for (j
= 0; j
< (1 << (shift
+ 4)); j
++)
2054 /* Print the jump table used to index an opcode into a switch
2058 dumptable (name
, size
, start
)
2068 printf ("unsigned char %s[%d]={\n", name
, size
);
2069 while (i
< start
+ size
)
2073 printf ("/* 0x%x */\n", i
);
2080 printf ("%2d", table
[i
+ j
+ k
]);
2099 static int index
= 1;
2102 for (; p
->name
; p
++)
2105 expand_opcode (12, 0, p
->index
, p
->code
);
2109 /* Table already contains all the switch case tags for 16-bit opcode double
2110 data transfer (ddt) insns, and the switch case tag for processing parallel
2111 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2112 latter tag to represent all combinations of ppi with ddt. */
2118 for (i
= 0xf000; i
< 0xf400; i
++)
2120 table
[i
+ 0x800] = table
[0xf800];
2127 for (; p
->name
; p
++)
2136 printf (" /* %s %s */\n", p
->name
, p
->code
);
2137 printf (" case %d: \n", p
->index
);
2145 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2157 printf (" int n = (iword >>8) & 0xf;\n");
2162 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2166 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2171 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2180 printf (" int m = (iword >>4) & 0xf;\n");
2184 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2188 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2192 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2196 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2201 printf (" int i = (iword & 0x");
2236 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2237 sextbit
- 1, sextbit
- 1);
2241 printf (" TB(m,n);\n");
2243 printf (" TL(m);\n");
2245 printf (" TL(n);\n");
2250 for (r
= p
->refs
; *r
; r
++)
2252 if (*r
== '0') printf(" CREF(0);\n");
2253 if (*r
== '8') printf(" CREF(8);\n");
2254 if (*r
== '9') printf(" CREF(9);\n");
2255 if (*r
== 'n') printf(" CREF(n);\n");
2256 if (*r
== 'm') printf(" CREF(m);\n");
2261 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2265 printf (" %s\n", p
->stuff
[j
]);
2273 for (r
= p
->defs
; *r
; r
++)
2275 if (*r
== '0') printf(" CDEF(0);\n");
2276 if (*r
== 'n') printf(" CDEF(n);\n");
2277 if (*r
== 'm') printf(" CDEF(m);\n");
2281 printf (" break;\n");
2290 printf (" switch (jump_table[iword]) {\n");
2292 gensim_caselist (tab
);
2293 gensim_caselist (movsxy_tab
);
2295 printf (" default:\n");
2297 printf (" RAISE_EXCEPTION (SIGILL);\n");
2308 for (p
= tab
; p
->name
; p
++)
2311 printf ("#define OPC_");
2315 if (isalpha(*s
)) printf("%c", *s
);
2316 if (*s
== ' ') printf("_");
2317 if (*s
== '@') printf("ind_");
2318 if (*s
== ',') printf("_");
2321 printf(" %d\n",p
->index
);
2325 static int ppi_index
;
2327 /* Take a ppi code, expand all varying fields in it and fill all the
2328 right entries in 'table' with the opcode index. */
2331 expand_ppi_code (val
, i
, s
)
2343 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n",
2347 /* The last eight bits are disregarded for the switch table. */
2365 expand_ppi_code (val
, i
, s
);
2372 expand_ppi_code (val
, ppi_index
++, s
);
2374 expand_ppi_code (val
, i
, s
);
2387 for (p
= ppi_tab
; p
->name
; p
++)
2389 p
->index
= ppi_index
++;
2390 expand_ppi_code (0, p
->index
, p
->code
);
2399 printf ("#define DSR_MASK_G 0x80\n");
2400 printf ("#define DSR_MASK_Z 0x40\n");
2401 printf ("#define DSR_MASK_N 0x20\n");
2402 printf ("#define DSR_MASK_V 0x10\n");
2404 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2405 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2406 printf (" if (overflow && S) \\\n");
2408 printf (" if (res_grd & 0x80) \\\n");
2410 printf (" res = 0x80000000; \\\n");
2411 printf (" res_grd |= 0xff; \\\n");
2413 printf (" else \\\n");
2415 printf (" res = 0x7fffffff; \\\n");
2416 printf (" res_grd &= ~0xff; \\\n");
2418 printf (" overflow = 0; \\\n");
2420 printf ("} while (0)\n");
2422 printf ("#define ADD_SUB_GE \\\n");
2423 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2425 printf ("static void\n");
2426 printf ("ppi_insn (iword)\n");
2427 printf (" int iword;\n");
2429 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2430 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2431 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2432 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2433 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2434 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2436 printf (" int z;\n");
2437 printf (" int res, res_grd;\n");
2438 printf (" int carry, overflow, greater_equal;\n");
2440 printf (" switch (ppi_table[iword >> 8]) {\n");
2442 for (; p
->name
; p
++)
2450 printf (" /* %s %s */\n", p
->name
, p
->code
);
2451 printf (" case %d: \n", p
->index
);
2454 for (shift
= 16; *s
; )
2459 printf (" int i = (iword >> 4) & 0x7f;\n");
2469 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2475 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2476 printf ("\treturn;\n");
2478 printf (" case %d: \n", p
->index
+ 1);
2490 printf (" z = iword & 0xf;\n");
2498 else if (havedecl
== 2)
2500 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2505 (havedecl
== 2 ? " " : ""),
2513 printf (" if (iword & 0x200)\n");
2514 printf (" goto assign_z;\n");
2516 printf (" break;\n");
2520 printf (" default:\n");
2522 printf (" RAISE_EXCEPTION (SIGILL);\n");
2523 printf (" return;\n");
2526 printf (" DSR &= ~0xf1;\n");
2527 printf (" if (res || res_grd)\n");
2528 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2530 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2531 printf (" assign_dc:\n");
2532 printf (" switch (DSR >> 1 & 7)\n");
2534 printf (" case 0: /* Carry Mode */\n");
2535 printf (" DSR |= carry;\n");
2536 printf (" case 1: /* Negative Value Mode */\n");
2537 printf (" DSR |= res_grd >> 7 & 1;\n");
2538 printf (" case 2: /* Zero Value Mode */\n");
2539 printf (" DSR |= DSR >> 6 & 1;\n");
2540 printf (" case 3: /* Overflow mode\n");
2541 printf (" DSR |= overflow >> 4;\n");
2542 printf (" case 4: /* Signed Greater Than Mode */\n");
2543 printf (" DSR |= DSR >> 7 & 1;\n");
2544 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2545 printf (" DSR |= greater_equal >> 7;\n");
2547 printf (" assign_z:\n");
2548 printf (" if (0xa05f >> z & 1)\n");
2550 printf (" RAISE_EXCEPTION (SIGILL);\n");
2551 printf (" return;\n");
2553 printf (" DSP_R (z) = res;\n");
2554 printf (" DSP_GRD (z) = res_grd;\n");
2563 /* verify the table before anything else */
2566 for (p
= tab
; p
->name
; p
++)
2568 /* check that the code field contains 16 bits */
2569 if (strlen (p
->code
) != 16)
2571 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2572 p
->code
, strlen (p
->code
), p
->name
);
2578 /* now generate the requested data */
2581 if (strcmp (av
[1], "-t") == 0)
2585 else if (strcmp (av
[1], "-d") == 0)
2589 else if (strcmp (av
[1], "-s") == 0)
2592 dumptable ("sh_jump_table", 1 << 16, 0);
2594 memset (table
, 0, sizeof table
);
2595 filltable (movsxy_tab
);
2597 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2599 memset (table
, 0, sizeof table
);
2601 dumptable ("ppi_table", 1 << 8, 0);
2603 else if (strcmp (av
[1], "-x") == 0)
2606 filltable (movsxy_tab
);
2609 else if (strcmp (av
[1], "-p") == 0)
2616 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.101915 seconds and 4 git commands to generate.