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", "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",
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", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
524 "CREG (m) = RLAT (R[n]);",
526 "/* FIXME: user mode */",
528 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
530 "SET_SR (RLAT (R[n]));",
532 "/* FIXME: user mode */",
534 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
536 "SET_MOD (RLAT (R[n]));",
540 { "n", "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", "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", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
571 "SET_FPSCR (RLAT(R[n]));",
575 { "", "", "ldtlb", "0000000000111000",
576 "/* FIXME: XXX*/ abort();",
579 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
580 "trap (255, R0, PC, memory, maskl, maskw, endianw);",
581 "/* FIXME: mac.l support */",
584 { "nm", "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 { "nm", "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 { "n", "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 { "n", "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 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
754 "/* We don't simulate cache, so this insn is identical to mov. */",
756 "WLAT (R[n], R[0]);",
759 { "n", "", "movt <REG_N>", "0000nnnn00101001",
763 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
764 "MACL = ((int)R[n]) * ((int)R[m]);",
767 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
768 "MACL = R[n] * R[m];",
772 /* muls.w - see muls */
773 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
774 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
777 /* mulu.w - see mulu */
778 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
779 "MACL = (((unsigned int)(unsigned short)R[n])",
780 " * ((unsigned int)(unsigned short)R[m]));",
783 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
787 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
789 "SET_SR_T (ult > 0);",
790 "R[n] = ult - R[m];",
791 "SET_SR_T (T || (R[n] > ult));",
794 { "", "", "nop", "0000000000001001",
798 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
802 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
803 "RSBAT (R[n]); /* Take exceptions like byte load. */",
804 "/* FIXME: Cache not implemented */",
807 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
808 "RSBAT (R[n]); /* Take exceptions like byte load. */",
809 "/* FIXME: Cache not implemented */",
812 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
813 "RSBAT (R[n]); /* Take exceptions like byte load. */",
814 "/* FIXME: Cache not implemented */",
817 { "0", "", "or #<imm>,R0", "11001011i8*1....",
820 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
823 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
825 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
828 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
829 "/* Except for the effect on the cache - which is not simulated -",
830 " this is like a nop. */",
833 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
835 "R[n] = (R[n] << 1) | T;",
839 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
841 "R[n] = (UR[n] >> 1) | (T << 31);",
845 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
846 "SET_SR_T (R[n] < 0);",
851 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
852 "SET_SR_T (R[n] & 1);",
853 "R[n] = UR[n] >> 1;",
854 "R[n] |= (T << 31);",
857 { "", "", "rte", "0000000000101011",
861 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
863 "SET_SR (RLAT (R[15]) & 0x3f3);",
865 "Delay_Slot (PC + 2);",
868 "SET_NIP (PT2H (SPC));",
870 "Delay_Slot (PC + 2);",
874 { "", "", "rts", "0000000000001011",
875 "SET_NIP (PT2H (PR));",
877 "Delay_Slot (PC + 2);",
881 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
884 { "", "", "setrc #<imm>", "10000010i8*1....",
885 /* It would be more realistic to let loop_start point to some static
886 memory that contains an illegal opcode and then give a bus error when
887 the loop is eventually encountered, but it seems not only simpler,
888 but also more debugging-friendly to just catch the failure here. */
889 "if (BUSERROR (RS | RE, maskw))",
890 " RAISE_EXCEPTION (SIGILL);",
893 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
894 " CHECK_INSN_PTR (insn_ptr);",
898 { "", "", "sets", "0000000001011000",
902 { "", "", "sett", "0000000000011000",
906 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
907 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
910 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
911 "SET_SR_T (R[n] < 0);",
915 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
916 "SET_SR_T (R[n] & 1);",
920 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
921 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
924 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
925 "SET_SR_T (R[n] < 0);",
929 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
932 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
935 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
939 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
940 "SET_SR_T (R[n] & 1);",
941 "R[n] = UR[n] >> 1;",
944 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
945 "R[n] = UR[n] >> 2;",
947 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
948 "R[n] = UR[n] >> 8;",
950 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
951 "R[n] = UR[n] >> 16;",
954 { "", "", "sleep", "0000000000011011",
955 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
958 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
963 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
966 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
970 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
973 "WLAT (R[n], CREG (m));",
976 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
981 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
988 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
991 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
994 "WLAT (R[n], SREG (m));",
997 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1001 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1003 "SET_SR_T (ult > R[n]);",
1004 "R[n] = ult - R[m];",
1005 "SET_SR_T (T || (R[n] > ult));",
1008 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1009 "ult = R[n] - R[m];",
1010 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1014 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1015 "R[n] = ((R[m] & 0xffff0000)",
1016 " | ((R[m] << 8) & 0xff00)",
1017 " | ((R[m] >> 8) & 0x00ff));",
1019 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1020 "R[n] = (((R[m] << 16) & 0xffff0000)",
1021 " | ((R[m] >> 16) & 0x00ffff));",
1024 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1026 "ult = RBAT(R[n]);",
1027 "SET_SR_T (ult == 0);",
1028 "WBAT(R[n],ult|0x80);",
1031 { "0", "", "trapa #<imm>", "11000011i8*1....",
1032 "long imm = 0xff & i;",
1033 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1034 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1039 " WLAT (R[15], GET_SR());",
1041 " WLAT (R[15], PH2T (PC + 2));",
1043 "else if (!SR_BL) {",
1045 " SPC = PH2T (PC + 2);",
1046 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1047 " /* FIXME: EXPEVT = 0x00000160; */",
1049 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1053 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1054 "SET_SR_T ((R[n] & R[m]) == 0);",
1056 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1057 "SET_SR_T ((R0 & i) == 0);",
1059 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1061 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1064 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1067 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1070 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1072 "ult = RBAT (GBR+R0);",
1074 "WBAT (GBR + R0, ult);",
1077 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1078 "R[n] = (((R[n] >> 16) & 0xffff)",
1079 " | ((R[m] << 16) & 0xffff0000));",
1083 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1084 "divl(0,R[n],R[m]);",
1086 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1087 "divl(0,R[n],R[m]);",
1095 /* If this is disabled, the simulator speeds up by about 12% on a
1096 450 MHz PIII - 9% with ACE_FAST.
1097 Maybe we should have separate simulator loops? */
1099 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1102 "DSP_R (m) = RSWAT (R[n]) << 16;",
1103 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1105 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1107 "DSP_R (m) = RSWAT (R[n]) << 16;",
1108 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1110 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1112 "DSP_R (m) = RSWAT (R[n]) << 16;",
1113 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1116 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1118 "DSP_R (m) = RSWAT (R[n]) << 16;",
1119 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1122 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1125 "DSP_R (m) = RSWAT (R[n]);",
1127 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1129 "DSP_R (m) = RSWAT (R[n]);",
1131 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1133 "DSP_R (m) = RSWAT (R[n]);",
1136 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1138 "DSP_R (m) = RSWAT (R[n]);",
1141 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1144 "WWAT (R[n], DSP_R (m) >> 16);",
1146 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1148 "WWAT (R[n], DSP_R (m) >> 16);",
1150 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1152 "WWAT (R[n], DSP_R (m) >> 16);",
1155 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1157 "WWAT (R[n], DSP_R (m) >> 16);",
1160 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1163 "WWAT (R[n], SEXT (DSP_R (m)));",
1165 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1167 "WWAT (R[n], SEXT (DSP_R (m)));",
1169 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1171 "WWAT (R[n], SEXT (DSP_R (m)));",
1174 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1176 "WWAT (R[n], SEXT (DSP_R (m)));",
1179 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1182 "DSP_R (m) = RLAT (R[n]);",
1183 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1185 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1187 "DSP_R (m) = RLAT (R[n]);",
1188 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1190 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1192 "DSP_R (m) = RLAT (R[n]);",
1193 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1196 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1198 "DSP_R (m) = RLAT (R[n]);",
1199 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1202 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1205 "WLAT (R[n], DSP_R (m));",
1207 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1209 "WLAT (R[n], DSP_R (m));",
1211 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1213 "WLAT (R[n], DSP_R (m));",
1216 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1218 "WLAT (R[n], DSP_R (m));",
1221 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1224 "WLAT (R[n], SEXT (DSP_R (m)));",
1226 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1228 "WLAT (R[n], SEXT (DSP_R (m)));",
1230 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1232 "WLAT (R[n], SEXT (DSP_R (m)));",
1235 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1237 "WLAT (R[n], SEXT (DSP_R (m)));",
1240 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1241 "DSP_R (m) = RSWAT (R[n]) << 16;",
1242 "iword &= 0xfd53; goto top;",
1244 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1245 "DSP_R (m) = RSWAT (R[n]) << 16;",
1246 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1247 "iword &= 0xfd53; goto top;",
1249 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1250 "DSP_R (m) = RSWAT (R[n]) << 16;",
1251 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1252 "iword &= 0xfd53; goto top;",
1254 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1255 "WWAT (R[n], DSP_R (m) >> 16);",
1256 "iword &= 0xfd53; goto top;",
1258 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1259 "WWAT (R[n], DSP_R (m) >> 16);",
1260 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1261 "iword &= 0xfd53; goto top;",
1263 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
1264 "WWAT (R[n], DSP_R (m) >> 16);",
1265 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1266 "iword &= 0xfd53; goto top;",
1268 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1269 "DSP_R (m) = RSWAT (R[n]) << 16;",
1271 { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
1272 "DSP_R (m) = RSWAT (R[n]) << 16;",
1273 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1275 { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000010",
1276 "DSP_R (m) = RSWAT (R[n]) << 16;",
1277 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1279 { "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
1280 "WWAT (R[n], DSP_R (m) >> 16);",
1282 { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
1283 "WWAT (R[n], DSP_R (m) >> 16);",
1284 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1286 { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010010",
1287 "WWAT (R[n], DSP_R (m) >> 16);",
1288 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1290 { "", "", "nopx nopy", "1111000000000000",
1293 { "", "", "ppi", "1111100000000000",
1294 "ppi_insn (RIAT (nip));",
1296 "iword &= 0xf7ff; goto top;",
1303 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1304 "int Sz = DSP_R (z) & 0xffff0000;",
1308 "else if (i >= 128 - 16)",
1309 " res = Sz >> 128 - i;",
1312 " RAISE_EXCEPTION (SIGILL);",
1315 "res &= 0xffff0000;",
1319 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1320 "int Sz = DSP_R (z);",
1321 "int Sz_grd = GET_DSP_GRD (z);",
1333 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1335 " res_grd = SEXT (res_grd);",
1336 " carry = res_grd & 1;",
1338 "else if (i >= 96)",
1343 " res_grd = SIGN32 (Sz_grd);",
1348 " res = Sz >> i | Sz_grd << 32 - i;",
1349 " res_grd = Sz_grd >> i;",
1351 " carry = Sz >> (i - 1) & 1;",
1355 " RAISE_EXCEPTION (SIGILL);",
1358 "COMPUTE_OVERFLOW;",
1359 "greater_equal = 0;",
1361 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1362 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1363 "if (res == 0x80000000)",
1364 " res = 0x7fffffff;",
1366 "DSP_GRD (g) = SIGN32 (res);",
1369 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1370 "int Sx = DSP_R (x);",
1371 "int Sx_grd = GET_DSP_GRD (x);",
1372 "int Sy = DSP_R (y);",
1373 "int Sy_grd = SIGN32 (Sy);",
1375 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1376 "if (res == 0x80000000)",
1377 " res = 0x7fffffff;",
1379 "DSP_GRD (g) = SIGN32 (res);",
1383 "carry = (unsigned) res > (unsigned) Sx;",
1384 "res_grd = Sx_grd - Sy_grd - carry;",
1385 "COMPUTE_OVERFLOW;",
1388 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1389 "int Sx = DSP_R (x);",
1390 "int Sx_grd = GET_DSP_GRD (x);",
1391 "int Sy = DSP_R (y);",
1392 "int Sy_grd = SIGN32 (Sy);",
1394 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1395 "if (res == 0x80000000)",
1396 " res = 0x7fffffff;",
1398 "DSP_GRD (g) = SIGN32 (res);",
1402 "carry = (unsigned) res < (unsigned) Sx;",
1403 "res_grd = Sx_grd + Sy_grd + carry;",
1404 "COMPUTE_OVERFLOW;",
1406 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1407 "int Sx = DSP_R (x);",
1408 "int Sx_grd = GET_DSP_GRD (x);",
1409 "int Sy = DSP_R (y);",
1410 "int Sy_grd = SIGN32 (Sy);",
1412 "res = Sx - Sy - (DSR & 1);",
1413 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1414 "res_grd = Sx_grd + Sy_grd + carry;",
1415 "COMPUTE_OVERFLOW;",
1418 "if (res || res_grd)\n",
1419 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1421 " DSR |= DSR_MASK_Z | overflow;\n",
1425 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1426 "int Sx = DSP_R (x);",
1427 "int Sx_grd = GET_DSP_GRD (x);",
1428 "int Sy = DSP_R (y);",
1429 "int Sy_grd = SIGN32 (Sy);",
1431 "res = Sx + Sy + (DSR & 1);",
1432 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1433 "res_grd = Sx_grd + Sy_grd + carry;",
1434 "COMPUTE_OVERFLOW;",
1437 "if (res || res_grd)\n",
1438 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1440 " DSR |= DSR_MASK_Z | overflow;\n",
1444 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1445 "int Sx = DSP_R (x);",
1446 "int Sx_grd = GET_DSP_GRD (x);",
1447 "int Sy = DSP_R (y);",
1448 "int Sy_grd = SIGN32 (Sy);",
1450 "z = 17; /* Ignore result. */",
1452 "carry = (unsigned) res > (unsigned) Sx;",
1453 "res_grd = Sx_grd - Sy_grd - carry;",
1454 "COMPUTE_OVERFLOW;",
1457 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1459 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1461 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1463 "res_grd = GET_DSP_GRD (x);",
1469 " carry = (res != 0); /* The manual has a bug here. */",
1470 " res_grd = -res_grd - carry;",
1472 "COMPUTE_OVERFLOW;",
1473 "/* ??? The re-computing of overflow after",
1474 " saturation processing is specific to pabs. */",
1475 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1478 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1479 "int Sx = DSP_R (x);",
1480 "int Sx_grd = GET_DSP_GRD (x);",
1482 "res = (Sx + 0x8000) & 0xffff0000;",
1483 "carry = (unsigned) res < (unsigned) Sx;",
1484 "res_grd = Sx_grd + carry;",
1485 "COMPUTE_OVERFLOW;",
1488 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1492 "greater_equal = DSR_MASK_G;",
1502 " res = 0x7fffffff;",
1505 " overflow = DSR_MASK_V;",
1506 " greater_equal = 0;",
1511 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1512 "int Sy = DSP_R (y);",
1513 "int Sy_grd = SIGN32 (Sy);",
1515 "res = (Sy + 0x8000) & 0xffff0000;",
1516 "carry = (unsigned) res < (unsigned) Sy;",
1517 "res_grd = Sy_grd + carry;",
1518 "COMPUTE_OVERFLOW;",
1521 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1522 "int Sx = DSP_R (x) & 0xffff0000;",
1523 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1527 "else if (Sy >= 128 - 16)",
1528 " res = Sx >> 128 - Sy;",
1531 " RAISE_EXCEPTION (SIGILL);",
1534 "goto cond_logical;",
1536 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1537 "int Sx = DSP_R (x);",
1538 "int Sx_grd = GET_DSP_GRD (x);",
1539 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1551 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1553 " res_grd = SEXT (res_grd);",
1554 " carry = res_grd & 1;",
1556 "else if (Sy >= 96)",
1561 " res_grd = SIGN32 (Sx_grd);",
1566 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1567 " res_grd = Sx_grd >> Sy;",
1569 " carry = Sx >> (Sy - 1) & 1;",
1573 " RAISE_EXCEPTION (SIGILL);",
1576 "COMPUTE_OVERFLOW;",
1577 "greater_equal = 0;",
1579 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1580 "int Sx = DSP_R (x);",
1581 "int Sx_grd = GET_DSP_GRD (x);",
1582 "int Sy = DSP_R (y);",
1583 "int Sy_grd = SIGN32 (Sy);",
1586 "carry = (unsigned) res > (unsigned) Sx;",
1587 "res_grd = Sx_grd - Sy_grd - carry;",
1588 "COMPUTE_OVERFLOW;",
1591 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1592 "int Sx = DSP_R (x);",
1593 "int Sx_grd = GET_DSP_GRD (x);",
1594 "int Sy = DSP_R (y);",
1595 "int Sy_grd = SIGN32 (Sy);",
1598 "carry = (unsigned) res < (unsigned) Sx;",
1599 "res_grd = Sx_grd + Sy_grd + carry;",
1600 "COMPUTE_OVERFLOW;",
1603 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1604 "res = DSP_R (x) & DSP_R (y);",
1606 "res &= 0xffff0000;",
1608 "if (iword & 0x200)\n",
1609 " goto assign_z;\n",
1613 "greater_equal = 0;",
1616 " DSR |= res >> 26 & DSR_MASK_N;\n",
1618 " DSR |= DSR_MASK_Z;\n",
1619 "goto assign_dc;\n",
1621 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1622 "res = DSP_R (x) ^ DSP_R (y);",
1623 "goto cond_logical;",
1625 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1626 "res = DSP_R (x) | DSP_R (y);",
1627 "goto cond_logical;",
1629 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1630 "int Sx = DSP_R (x);",
1631 "int Sx_grd = GET_DSP_GRD (x);",
1633 "res = Sx - 0x10000;",
1634 "carry = res > Sx;",
1635 "res_grd = Sx_grd - carry;",
1636 "COMPUTE_OVERFLOW;",
1638 "res &= 0xffff0000;",
1640 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1641 "int Sx = DSP_R (x);",
1642 "int Sx_grd = GET_DSP_GRD (x);",
1644 "res = Sx + 0x10000;",
1645 "carry = res < Sx;",
1646 "res_grd = Sx_grd + carry;",
1647 "COMPUTE_OVERFLOW;",
1649 "res &= 0xffff0000;",
1651 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1652 "int Sy = DSP_R (y);",
1653 "int Sy_grd = SIGN32 (Sy);",
1655 "res = Sy - 0x10000;",
1656 "carry = res > Sy;",
1657 "res_grd = Sy_grd - carry;",
1658 "COMPUTE_OVERFLOW;",
1660 "res &= 0xffff0000;",
1662 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1663 "int Sy = DSP_R (y);",
1664 "int Sy_grd = SIGN32 (Sy);",
1666 "res = Sy + 0x10000;",
1667 "carry = res < Sy;",
1668 "res_grd = Sy_grd + carry;",
1669 "COMPUTE_OVERFLOW;",
1671 "res &= 0xffff0000;",
1673 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1678 "greater_equal = 1;",
1680 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1681 "unsigned Sx = DSP_R (x);",
1682 "int Sx_grd = GET_DSP_GRD (x);",
1687 " Sx_grd = ~Sx_grd;",
1701 " if (Sx & ~0 << i)",
1709 "res_grd = SIGN32 (res);",
1714 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1715 "unsigned Sy = DSP_R (y);",
1724 " if (Sy & ~0 << i)",
1732 "res_grd = SIGN32 (res);",
1737 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1738 "int Sx = DSP_R (x);",
1739 "int Sx_grd = GET_DSP_GRD (x);",
1742 "carry = res != 0;",
1743 "res_grd = 0 - Sx_grd - carry;",
1744 "COMPUTE_OVERFLOW;",
1747 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1749 "res_grd = GET_DSP_GRD (x);",
1751 "COMPUTE_OVERFLOW;",
1754 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1755 "int Sy = DSP_R (y);",
1756 "int Sy_grd = SIGN32 (Sy);",
1759 "carry = res != 0;",
1760 "res_grd = 0 - Sy_grd - carry;",
1761 "COMPUTE_OVERFLOW;",
1764 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1766 "res_grd = SIGN32 (res);",
1768 "COMPUTE_OVERFLOW;",
1771 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1773 "res_grd = SIGN32 (res);",
1776 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1778 "res_grd = SIGN32 (res);",
1781 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1782 "if (0xa05f >> z & 1)",
1783 " RAISE_EXCEPTION (SIGILL);",
1785 " MACH = DSP_R (z);",
1788 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1789 "if (0xa05f >> z & 1)",
1790 " RAISE_EXCEPTION (SIGILL);",
1792 " MACL = DSP_R (z) = res;",
1798 /* Tables of things to put into enums for sh-opc.h */
1799 static char *nibble_type_list
[] =
1834 char *arg_type_list
[] =
1868 make_enum_list (name
, s
)
1873 printf ("typedef enum {\n");
1876 printf ("\t%s,\n", *s
);
1880 printf ("} %s;\n", name
);
1892 memcpy (bufa
, a
->code
, 4);
1893 memcpy (bufa
+ 4, a
->code
+ 12, 4);
1896 memcpy (bufb
, b
->code
, 4);
1897 memcpy (bufb
+ 4, b
->code
+ 12, 4);
1899 diff
= strcmp (bufa
, bufb
);
1900 /* Stabilize the sort, so that later entries can override more general
1901 preceding entries. */
1902 return diff
? diff
: a
- b
;
1916 qsort (tab
, len
, sizeof (*p
), qfunc
);
1924 for (p
= tab
; p
->name
; p
++)
1926 printf ("%s %-30s\n", p
->code
, p
->name
);
1932 /* Convert a string of 4 binary digits into an int */
1952 static unsigned char table
[1 << 16];
1954 /* Take an opcode expand all varying fields in it out and fill all the
1955 right entries in 'table' with the opcode index*/
1958 expand_opcode (shift
, val
, i
, s
)
1980 val
|= bton (s
) << shift
;
1981 if (s
[2] == '0' || s
[2] == '1')
1982 expand_opcode (shift
- 4, val
, i
, s
+ 4);
1983 else if (s
[2] == 'N')
1984 for (j
= 0; j
< 4; j
++)
1985 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
1986 else if (s
[2] == 'x')
1987 for (j
= 0; j
< 4; j
+= 2)
1988 for (m
= 0; m
< 32; m
++)
1990 /* Ignore illegal nopy */
1991 if ((m
& 7) == 0 && m
!= 0)
1993 mv
= m
& 3 | (m
& 4) << 2 | (m
& 8) << 3 | (m
& 16) << 4;
1994 expand_opcode (shift
- 4, val
| mv
| (j
<< shift
), i
,
1997 else if (s
[2] == 'y')
1998 for (j
= 0; j
< 2; j
++)
1999 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2004 for (j
= 0; j
< 16; j
++)
2006 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2011 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2012 for (j
= 5; j
< 16; j
++)
2014 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2018 for (j
= 13; j
<= 15; j
+=2)
2019 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2022 /* System registers mach, macl, pr: */
2023 for (j
= 0; j
< 3; j
++)
2024 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2025 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2026 for (j
= 5; j
< 12; j
++)
2027 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2031 val
|= bton (s
) << shift
;
2032 for (j
= 0; j
< 16; j
+= 8)
2033 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2037 val
|= bton (s
) << shift
;
2038 for (j
= 0; j
< 8; j
+= 4)
2039 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
2043 for (j
= 0; j
< (1 << (shift
+ 4)); j
++)
2051 /* Print the jump table used to index an opcode into a switch
2055 dumptable (name
, size
, start
)
2065 printf ("unsigned char %s[%d]={\n", name
, size
);
2066 while (i
< start
+ size
)
2070 printf ("/* 0x%x */\n", i
);
2077 printf ("%2d", table
[i
+ j
+ k
]);
2096 static int index
= 1;
2099 for (; p
->name
; p
++)
2102 expand_opcode (12, 0, p
->index
, p
->code
);
2106 /* Table already contais all the switch case tags for 16-bit opcode double
2107 data transfer (ddt) insns, and the switch case tag for processing parallel
2108 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2109 latter tag to represent all combinations of ppi with ddt. */
2115 for (i
= 0xf000; i
< 0xf400; i
++)
2117 table
[i
+ 0x800] = table
[0xf800];
2124 for (; p
->name
; p
++)
2133 printf (" /* %s %s */\n", p
->name
, p
->code
);
2134 printf (" case %d: \n", p
->index
);
2141 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2153 printf (" int n = (iword >>8) & 0xf;\n");
2158 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2162 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2167 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2176 printf (" int m = (iword >>4) & 0xf;\n");
2180 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2184 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2188 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2192 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2197 printf (" int i = (iword & 0x");
2232 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2233 sextbit
- 1, sextbit
- 1);
2237 printf (" TB(m,n);\n");
2239 printf (" TL(m);\n");
2241 printf (" TL(n);\n");
2246 for (r
= p
->refs
; *r
; r
++)
2248 if (*r
== '0') printf(" CREF(0);\n");
2249 if (*r
== '8') printf(" CREF(8);\n");
2250 if (*r
== '9') printf(" CREF(9);\n");
2251 if (*r
== 'n') printf(" CREF(n);\n");
2252 if (*r
== 'm') printf(" CREF(m);\n");
2257 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2261 printf (" %s\n", p
->stuff
[j
]);
2269 for (r
= p
->defs
; *r
; r
++)
2271 if (*r
== '0') printf(" CDEF(0);\n");
2272 if (*r
== 'n') printf(" CDEF(n);\n");
2273 if (*r
== 'm') printf(" CDEF(m);\n");
2277 printf (" break;\n");
2286 printf (" switch (jump_table[iword]) {\n");
2288 gensim_caselist (tab
);
2289 gensim_caselist (movsxy_tab
);
2291 printf (" default:\n");
2293 printf (" RAISE_EXCEPTION (SIGILL);\n");
2304 for (p
= tab
; p
->name
; p
++)
2307 printf ("#define OPC_");
2311 if (isalpha(*s
)) printf("%c", *s
);
2312 if (*s
== ' ') printf("_");
2313 if (*s
== '@') printf("ind_");
2314 if (*s
== ',') printf("_");
2317 printf(" %d\n",p
->index
);
2321 static int ppi_index
;
2323 /* Take an ppi code, expand all varying fields in it and fill all the
2324 right entries in 'table' with the opcode index. */
2327 expand_ppi_code (val
, i
, s
)
2339 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n",
2343 /* The last eight bits are disregarded for the switch table. */
2361 expand_ppi_code (val
, i
, s
);
2368 expand_ppi_code (val
, ppi_index
++, s
);
2370 expand_ppi_code (val
, i
, s
);
2383 for (p
= ppi_tab
; p
->name
; p
++)
2385 p
->index
= ppi_index
++;
2386 expand_ppi_code (0, p
->index
, p
->code
);
2395 printf ("#define DSR_MASK_G 0x80\n");
2396 printf ("#define DSR_MASK_Z 0x40\n");
2397 printf ("#define DSR_MASK_N 0x20\n");
2398 printf ("#define DSR_MASK_V 0x10\n");
2400 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2401 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2402 printf (" if (overflow && S) \\\n");
2404 printf (" if (res_grd & 0x80) \\\n");
2406 printf (" res = 0x80000000; \\\n");
2407 printf (" res_grd |= 0xff; \\\n");
2409 printf (" else \\\n");
2411 printf (" res = 0x7fffffff; \\\n");
2412 printf (" res_grd &= ~0xff; \\\n");
2414 printf (" overflow = 0; \\\n");
2416 printf ("} while (0)\n");
2418 printf ("#define ADD_SUB_GE \\\n");
2419 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2421 printf ("static void\n");
2422 printf ("ppi_insn (iword)\n");
2423 printf (" int iword;\n");
2425 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2426 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2427 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2428 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2429 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2430 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2432 printf (" int z;\n");
2433 printf (" int res, res_grd;\n");
2434 printf (" int carry, overflow, greater_equal;\n");
2436 printf (" switch (ppi_table[iword >> 8]) {\n");
2438 for (; p
->name
; p
++)
2446 printf (" /* %s %s */\n", p
->name
, p
->code
);
2447 printf (" case %d: \n", p
->index
);
2450 for (shift
= 16; *s
; )
2455 printf (" int i = (iword >> 4) & 0x7f;\n");
2465 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2471 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2472 printf ("\treturn;\n");
2474 printf (" case %d: \n", p
->index
+ 1);
2486 printf (" z = iword & 0xf;\n");
2494 else if (havedecl
== 2)
2496 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2501 (havedecl
== 2 ? " " : ""),
2509 printf (" if (iword & 0x200)\n");
2510 printf (" goto assign_z;\n");
2512 printf (" break;\n");
2516 printf (" default:\n");
2518 printf (" RAISE_EXCEPTION (SIGILL);\n");
2519 printf (" return;\n");
2522 printf (" DSR &= ~0xf1;\n");
2523 printf (" if (res || res_grd)\n");
2524 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2526 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2527 printf (" assign_dc:\n");
2528 printf (" switch (DSR >> 1 & 7)\n");
2530 printf (" case 0: /* Carry Mode */\n");
2531 printf (" DSR |= carry;\n");
2532 printf (" case 1: /* Negative Value Mode */\n");
2533 printf (" DSR |= res_grd >> 7 & 1;\n");
2534 printf (" case 2: /* Zero Value Mode */\n");
2535 printf (" DSR |= DSR >> 6 & 1;\n");
2536 printf (" case 3: /* Overflow mode\n");
2537 printf (" DSR |= overflow >> 4;\n");
2538 printf (" case 4: /* Signed Greater Than Mode */\n");
2539 printf (" DSR |= DSR >> 7 & 1;\n");
2540 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2541 printf (" DSR |= greater_equal >> 7;\n");
2543 printf (" assign_z:\n");
2544 printf (" if (0xa05f >> z & 1)\n");
2546 printf (" RAISE_EXCEPTION (SIGILL);\n");
2547 printf (" return;\n");
2549 printf (" DSP_R (z) = res;\n");
2550 printf (" DSP_GRD (z) = res_grd;\n");
2559 /* verify the table before anything else */
2562 for (p
= tab
; p
->name
; p
++)
2564 /* check that the code field contains 16 bits */
2565 if (strlen (p
->code
) != 16)
2567 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2568 p
->code
, strlen (p
->code
), p
->name
);
2574 /* now generate the requested data */
2577 if (strcmp (av
[1], "-t") == 0)
2581 else if (strcmp (av
[1], "-d") == 0)
2585 else if (strcmp (av
[1], "-s") == 0)
2588 dumptable ("sh_jump_table", 1 << 16, 0);
2590 memset (table
, 0, sizeof table
);
2591 filltable (movsxy_tab
);
2593 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2595 memset (table
, 0, sizeof table
);
2597 dumptable ("ppi_table", 1 << 8, 0);
2599 else if (strcmp (av
[1], "-x") == 0)
2602 filltable (movsxy_tab
);
2605 else if (strcmp (av
[1], "-p") == 0)
2612 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.190151 seconds and 5 git commands to generate.