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 { "", "", "fsca", "1111nnn011111101",
454 " RAISE_EXCEPTION (SIGILL);",
457 " SET_FR (n, fsca_s (FPUL, &sin));",
458 " SET_FR (n+1, fsca_s (FPUL, &cos));",
463 { "", "", "fschg", "1111001111111101",
464 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
468 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
469 "FP_UNARY(n, sqrt);",
473 { "", "", "fsrra", "1111nnnn01111101",
475 " RAISE_EXCEPTION (SIGILL);",
477 " SET_FR (n, fsrra_s (FR (n)));",
481 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
486 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
489 " if (DR(n) != DR(n)) /* NaN */",
490 " FPUL = 0x80000000;",
492 " FPUL = (int)DR(n);",
495 "if (FR(n) != FR(n)) /* NaN */",
496 " FPUL = 0x80000000;",
498 " FPUL = (int)FR(n);",
502 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
512 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
513 "SET_NIP (PT2H (R[n]));",
515 "Delay_Slot (PC + 2);",
518 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
519 "PR = PH2T (PC + 4);",
521 " gotcall (PR, R[n]);",
522 "SET_NIP (PT2H (R[n]));",
524 "Delay_Slot (PC + 2);",
527 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
529 "/* FIXME: user mode */",
531 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
533 "/* FIXME: user mode */",
535 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
539 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
541 "/* FIXME: user mode */",
544 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
546 "CREG (m) = RLAT (R[n]);",
548 "/* FIXME: user mode */",
550 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
552 "SET_SR (RLAT (R[n]));",
554 "/* FIXME: user mode */",
556 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
558 "SET_MOD (RLAT (R[n]));",
562 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
564 "DBR = RLAT (R[n]);",
566 "/* FIXME: user mode */",
571 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
572 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
574 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
575 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
578 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
581 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
583 "SREG (m) = RLAT(R[n]);",
586 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
587 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
590 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
591 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
593 "SET_FPSCR (RLAT(R[n]));",
597 { "", "", "ldtlb", "0000000000111000",
598 "/* We don't implement cache or tlb, so this is a noop. */",
601 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
602 "macl(&R0,memory,n,m);",
605 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
606 "macw(&R0,memory,n,m,endianw);",
609 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
612 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
616 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
618 "R0 = RSBAT (i + GBR);",
621 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
623 "R0 = RSBAT (i + R[m]);",
626 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
628 "R[n] = RSBAT (R0 + R[m]);",
631 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
633 "R[n] = RSBAT (R[m]);",
637 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
639 "WBAT (R[n], R[m]);",
641 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
643 "WBAT (i + GBR, R0);",
645 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
647 "WBAT (i + R[m], R0);",
649 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
651 "WBAT (R[n] + R0, R[m]);",
653 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
656 "WBAT (R[n], R[m]);",
658 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
660 "R[n] = RSBAT (R[m]);",
664 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
666 "R0 = RLAT (i + GBR);",
669 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
671 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
674 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
676 "R[n] = RLAT (i + R[m]);",
679 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
681 "R[n] = RLAT (R0 + R[m]);",
684 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
686 "R[n] = RLAT (R[m]);",
690 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
692 "R[n] = RLAT (R[m]);",
695 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
697 "WLAT (i + GBR, R0);",
699 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
701 "WLAT (i + R[n], R[m]);",
703 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
705 "WLAT (R0 + R[n], R[m]);",
707 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
710 "WLAT (R[n], R[m]);",
712 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
714 "WLAT (R[n], R[m]);",
717 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
719 "R0 = RSWAT (i + GBR);",
722 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
724 "R[n] = RSWAT (PH2T (PC + 4 + i));",
727 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
729 "R0 = RSWAT (i + R[m]);",
732 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
734 "R[n] = RSWAT (R0 + R[m]);",
737 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
739 "R[n] = RSWAT (R[m]);",
743 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
745 "R[n] = RSWAT (R[m]);",
748 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
750 "WWAT (i + GBR, R0);",
752 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
754 "WWAT (i + R[m], R0);",
756 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
758 "WWAT (R0 + R[n], R[m]);",
760 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
763 "WWAT (R[n], R[m]);",
765 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
767 "WWAT (R[n], R[m]);",
770 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
771 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
774 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
775 "/* We don't simulate cache, so this insn is identical to mov. */",
777 "WLAT (R[n], R[0]);",
780 { "n", "", "movt <REG_N>", "0000nnnn00101001",
784 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
785 "MACL = ((int)R[n]) * ((int)R[m]);",
788 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
789 "MACL = R[n] * R[m];",
793 /* muls.w - see muls */
794 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
795 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
798 /* mulu.w - see mulu */
799 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
800 "MACL = (((unsigned int)(unsigned short)R[n])",
801 " * ((unsigned int)(unsigned short)R[m]));",
804 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
808 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
810 "SET_SR_T (ult > 0);",
811 "R[n] = ult - R[m];",
812 "SET_SR_T (T || (R[n] > ult));",
815 { "", "", "nop", "0000000000001001",
819 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
823 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
824 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
825 "/* FIXME: Cache not implemented */",
828 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
829 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
830 "/* FIXME: Cache not implemented */",
833 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
834 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
835 "/* FIXME: Cache not implemented */",
838 { "0", "", "or #<imm>,R0", "11001011i8*1....",
841 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
844 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
846 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
849 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
850 "/* Except for the effect on the cache - which is not simulated -",
851 " this is like a nop. */",
854 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
856 "R[n] = (R[n] << 1) | T;",
860 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
862 "R[n] = (UR[n] >> 1) | (T << 31);",
866 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
867 "SET_SR_T (R[n] < 0);",
872 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
873 "SET_SR_T (R[n] & 1);",
874 "R[n] = UR[n] >> 1;",
875 "R[n] |= (T << 31);",
878 { "", "", "rte", "0000000000101011",
882 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
884 "SET_SR (RLAT (R[15]) & 0x3f3);",
886 "Delay_Slot (PC + 2);",
889 "SET_NIP (PT2H (SPC));",
891 "Delay_Slot (PC + 2);",
895 { "", "", "rts", "0000000000001011",
896 "SET_NIP (PT2H (PR));",
898 "Delay_Slot (PC + 2);",
902 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
905 { "", "", "setrc #<imm>", "10000010i8*1....",
906 /* It would be more realistic to let loop_start point to some static
907 memory that contains an illegal opcode and then give a bus error when
908 the loop is eventually encountered, but it seems not only simpler,
909 but also more debugging-friendly to just catch the failure here. */
910 "if (BUSERROR (RS | RE, maskw))",
911 " RAISE_EXCEPTION (SIGILL);",
914 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
915 " CHECK_INSN_PTR (insn_ptr);",
919 { "", "", "sets", "0000000001011000",
923 { "", "", "sett", "0000000000011000",
927 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
928 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
931 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
932 "SET_SR_T (R[n] < 0);",
936 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
937 "SET_SR_T (R[n] & 1);",
941 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
942 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
945 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
946 "SET_SR_T (R[n] < 0);",
950 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
953 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
956 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
960 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
961 "SET_SR_T (R[n] & 1);",
962 "R[n] = UR[n] >> 1;",
965 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
966 "R[n] = UR[n] >> 2;",
968 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
969 "R[n] = UR[n] >> 8;",
971 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
972 "R[n] = UR[n] >> 16;",
975 { "", "", "sleep", "0000000000011011",
976 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
979 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
984 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
987 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
991 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
994 "WLAT (R[n], CREG (m));",
997 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1000 "WLAT (R[n], SGR);",
1002 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1005 "WLAT (R[n], DBR);",
1009 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1012 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1015 "WLAT (R[n], SREG (m));",
1018 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1022 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1024 "SET_SR_T (ult > R[n]);",
1025 "R[n] = ult - R[m];",
1026 "SET_SR_T (T || (R[n] > ult));",
1029 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1030 "ult = R[n] - R[m];",
1031 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1035 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1036 "R[n] = ((R[m] & 0xffff0000)",
1037 " | ((R[m] << 8) & 0xff00)",
1038 " | ((R[m] >> 8) & 0x00ff));",
1040 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1041 "R[n] = (((R[m] << 16) & 0xffff0000)",
1042 " | ((R[m] >> 16) & 0x00ffff));",
1045 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1047 "ult = RBAT(R[n]);",
1048 "SET_SR_T (ult == 0);",
1049 "WBAT(R[n],ult|0x80);",
1052 { "0", "", "trapa #<imm>", "11000011i8*1....",
1053 "long imm = 0xff & i;",
1054 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1055 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1060 " WLAT (R[15], GET_SR());",
1062 " WLAT (R[15], PH2T (PC + 2));",
1064 "else if (!SR_BL) {",
1066 " SPC = PH2T (PC + 2);",
1067 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1068 " /* FIXME: EXPEVT = 0x00000160; */",
1070 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1074 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1075 "SET_SR_T ((R[n] & R[m]) == 0);",
1077 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1078 "SET_SR_T ((R0 & i) == 0);",
1080 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1082 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1085 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1088 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1091 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1093 "ult = RBAT (GBR+R0);",
1095 "WBAT (GBR + R0, ult);",
1098 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1099 "R[n] = (((R[n] >> 16) & 0xffff)",
1100 " | ((R[m] << 16) & 0xffff0000));",
1104 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1105 "divl(0,R[n],R[m]);",
1107 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1108 "divl(0,R[n],R[m]);",
1116 /* If this is disabled, the simulator speeds up by about 12% on a
1117 450 MHz PIII - 9% with ACE_FAST.
1118 Maybe we should have separate simulator loops? */
1120 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1123 "DSP_R (m) = RSWAT (R[n]) << 16;",
1124 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1126 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1128 "DSP_R (m) = RSWAT (R[n]) << 16;",
1129 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1131 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1133 "DSP_R (m) = RSWAT (R[n]) << 16;",
1134 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1137 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1139 "DSP_R (m) = RSWAT (R[n]) << 16;",
1140 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1143 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1146 "DSP_R (m) = RSWAT (R[n]);",
1148 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1150 "DSP_R (m) = RSWAT (R[n]);",
1152 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1154 "DSP_R (m) = RSWAT (R[n]);",
1157 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1159 "DSP_R (m) = RSWAT (R[n]);",
1162 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1165 "WWAT (R[n], DSP_R (m) >> 16);",
1167 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1169 "WWAT (R[n], DSP_R (m) >> 16);",
1171 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1173 "WWAT (R[n], DSP_R (m) >> 16);",
1176 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1178 "WWAT (R[n], DSP_R (m) >> 16);",
1181 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1184 "WWAT (R[n], SEXT (DSP_R (m)));",
1186 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1188 "WWAT (R[n], SEXT (DSP_R (m)));",
1190 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1192 "WWAT (R[n], SEXT (DSP_R (m)));",
1195 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1197 "WWAT (R[n], SEXT (DSP_R (m)));",
1200 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1203 "DSP_R (m) = RLAT (R[n]);",
1204 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1206 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1208 "DSP_R (m) = RLAT (R[n]);",
1209 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1211 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1213 "DSP_R (m) = RLAT (R[n]);",
1214 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1217 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1219 "DSP_R (m) = RLAT (R[n]);",
1220 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1223 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1226 "WLAT (R[n], DSP_R (m));",
1228 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1230 "WLAT (R[n], DSP_R (m));",
1232 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1234 "WLAT (R[n], DSP_R (m));",
1237 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1239 "WLAT (R[n], DSP_R (m));",
1242 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1245 "WLAT (R[n], SEXT (DSP_R (m)));",
1247 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1249 "WLAT (R[n], SEXT (DSP_R (m)));",
1251 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1253 "WLAT (R[n], SEXT (DSP_R (m)));",
1256 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1258 "WLAT (R[n], SEXT (DSP_R (m)));",
1261 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1262 "DSP_R (m) = RSWAT (R[n]) << 16;",
1263 "iword &= 0xfd53; goto top;",
1265 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1266 "DSP_R (m) = RSWAT (R[n]) << 16;",
1267 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1268 "iword &= 0xfd53; goto top;",
1270 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001100",
1271 "DSP_R (m) = RSWAT (R[n]) << 16;",
1272 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1273 "iword &= 0xfd53; goto top;",
1275 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1276 "WWAT (R[n], DSP_R (m) >> 16);",
1277 "iword &= 0xfd53; goto top;",
1279 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1280 "WWAT (R[n], DSP_R (m) >> 16);",
1281 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1282 "iword &= 0xfd53; goto top;",
1284 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
1285 "WWAT (R[n], DSP_R (m) >> 16);",
1286 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1287 "iword &= 0xfd53; goto top;",
1289 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1290 "DSP_R (m) = RSWAT (R[n]) << 16;",
1292 { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
1293 "DSP_R (m) = RSWAT (R[n]) << 16;",
1294 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1296 { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000011",
1297 "DSP_R (m) = RSWAT (R[n]) << 16;",
1298 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1300 { "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
1301 "WWAT (R[n], DSP_R (m) >> 16);",
1303 { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
1304 "WWAT (R[n], DSP_R (m) >> 16);",
1305 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1307 { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010011",
1308 "WWAT (R[n], DSP_R (m) >> 16);",
1309 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1311 { "", "", "nopx nopy", "1111000000000000",
1314 { "", "", "ppi", "1111100000000000",
1315 "ppi_insn (RIAT (nip));",
1317 "iword &= 0xf7ff; goto top;",
1324 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1325 "int Sz = DSP_R (z) & 0xffff0000;",
1329 "else if (i >= 128 - 16)",
1330 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1333 " RAISE_EXCEPTION (SIGILL);",
1336 "res &= 0xffff0000;",
1340 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1341 "int Sz = DSP_R (z);",
1342 "int Sz_grd = GET_DSP_GRD (z);",
1354 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1356 " res_grd = SEXT (res_grd);",
1357 " carry = res_grd & 1;",
1359 "else if (i >= 96)",
1364 " res_grd = SIGN32 (Sz_grd);",
1369 " res = Sz >> i | Sz_grd << 32 - i;",
1370 " res_grd = Sz_grd >> i;",
1372 " carry = Sz >> (i - 1) & 1;",
1376 " RAISE_EXCEPTION (SIGILL);",
1379 "COMPUTE_OVERFLOW;",
1380 "greater_equal = 0;",
1382 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1383 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1384 "if (res == 0x80000000)",
1385 " res = 0x7fffffff;",
1387 "DSP_GRD (g) = SIGN32 (res);",
1390 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1391 "int Sx = DSP_R (x);",
1392 "int Sx_grd = GET_DSP_GRD (x);",
1393 "int Sy = DSP_R (y);",
1394 "int Sy_grd = SIGN32 (Sy);",
1396 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1397 "if (res == 0x80000000)",
1398 " res = 0x7fffffff;",
1400 "DSP_GRD (g) = SIGN32 (res);",
1404 "carry = (unsigned) res > (unsigned) Sx;",
1405 "res_grd = Sx_grd - Sy_grd - carry;",
1406 "COMPUTE_OVERFLOW;",
1409 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
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 = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1416 "if (res == 0x80000000)",
1417 " res = 0x7fffffff;",
1419 "DSP_GRD (g) = SIGN32 (res);",
1423 "carry = (unsigned) res < (unsigned) Sx;",
1424 "res_grd = Sx_grd + Sy_grd + carry;",
1425 "COMPUTE_OVERFLOW;",
1427 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1428 "int Sx = DSP_R (x);",
1429 "int Sx_grd = GET_DSP_GRD (x);",
1430 "int Sy = DSP_R (y);",
1431 "int Sy_grd = SIGN32 (Sy);",
1433 "res = Sx - Sy - (DSR & 1);",
1434 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1435 "res_grd = Sx_grd + Sy_grd + carry;",
1436 "COMPUTE_OVERFLOW;",
1439 "if (res || res_grd)\n",
1440 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1442 " DSR |= DSR_MASK_Z | overflow;\n",
1446 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1447 "int Sx = DSP_R (x);",
1448 "int Sx_grd = GET_DSP_GRD (x);",
1449 "int Sy = DSP_R (y);",
1450 "int Sy_grd = SIGN32 (Sy);",
1452 "res = Sx + Sy + (DSR & 1);",
1453 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1454 "res_grd = Sx_grd + Sy_grd + carry;",
1455 "COMPUTE_OVERFLOW;",
1458 "if (res || res_grd)\n",
1459 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1461 " DSR |= DSR_MASK_Z | overflow;\n",
1465 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1466 "int Sx = DSP_R (x);",
1467 "int Sx_grd = GET_DSP_GRD (x);",
1468 "int Sy = DSP_R (y);",
1469 "int Sy_grd = SIGN32 (Sy);",
1471 "z = 17; /* Ignore result. */",
1473 "carry = (unsigned) res > (unsigned) Sx;",
1474 "res_grd = Sx_grd - Sy_grd - carry;",
1475 "COMPUTE_OVERFLOW;",
1478 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1480 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1482 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1484 "res_grd = GET_DSP_GRD (x);",
1490 " carry = (res != 0); /* The manual has a bug here. */",
1491 " res_grd = -res_grd - carry;",
1493 "COMPUTE_OVERFLOW;",
1494 "/* ??? The re-computing of overflow after",
1495 " saturation processing is specific to pabs. */",
1496 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1499 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1500 "int Sx = DSP_R (x);",
1501 "int Sx_grd = GET_DSP_GRD (x);",
1503 "res = (Sx + 0x8000) & 0xffff0000;",
1504 "carry = (unsigned) res < (unsigned) Sx;",
1505 "res_grd = Sx_grd + carry;",
1506 "COMPUTE_OVERFLOW;",
1509 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1513 "greater_equal = DSR_MASK_G;",
1523 " res = 0x7fffffff;",
1526 " overflow = DSR_MASK_V;",
1527 " greater_equal = 0;",
1532 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1533 "int Sy = DSP_R (y);",
1534 "int Sy_grd = SIGN32 (Sy);",
1536 "res = (Sy + 0x8000) & 0xffff0000;",
1537 "carry = (unsigned) res < (unsigned) Sy;",
1538 "res_grd = Sy_grd + carry;",
1539 "COMPUTE_OVERFLOW;",
1542 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1543 "int Sx = DSP_R (x) & 0xffff0000;",
1544 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1548 "else if (Sy >= 128 - 16)",
1549 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
1552 " RAISE_EXCEPTION (SIGILL);",
1555 "goto cond_logical;",
1557 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1558 "int Sx = DSP_R (x);",
1559 "int Sx_grd = GET_DSP_GRD (x);",
1560 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1572 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1574 " res_grd = SEXT (res_grd);",
1575 " carry = res_grd & 1;",
1577 "else if (Sy >= 96)",
1582 " res_grd = SIGN32 (Sx_grd);",
1587 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1588 " res_grd = Sx_grd >> Sy;",
1590 " carry = Sx >> (Sy - 1) & 1;",
1594 " RAISE_EXCEPTION (SIGILL);",
1597 "COMPUTE_OVERFLOW;",
1598 "greater_equal = 0;",
1600 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1601 "int Sx = DSP_R (x);",
1602 "int Sx_grd = GET_DSP_GRD (x);",
1603 "int Sy = DSP_R (y);",
1604 "int Sy_grd = SIGN32 (Sy);",
1607 "carry = (unsigned) res > (unsigned) Sx;",
1608 "res_grd = Sx_grd - Sy_grd - carry;",
1609 "COMPUTE_OVERFLOW;",
1612 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1613 "int Sx = DSP_R (x);",
1614 "int Sx_grd = GET_DSP_GRD (x);",
1615 "int Sy = DSP_R (y);",
1616 "int Sy_grd = SIGN32 (Sy);",
1619 "carry = (unsigned) res < (unsigned) Sx;",
1620 "res_grd = Sx_grd + Sy_grd + carry;",
1621 "COMPUTE_OVERFLOW;",
1624 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1625 "res = DSP_R (x) & DSP_R (y);",
1627 "res &= 0xffff0000;",
1629 "if (iword & 0x200)\n",
1630 " goto assign_z;\n",
1634 "greater_equal = 0;",
1637 " DSR |= res >> 26 & DSR_MASK_N;\n",
1639 " DSR |= DSR_MASK_Z;\n",
1640 "goto assign_dc;\n",
1642 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1643 "res = DSP_R (x) ^ DSP_R (y);",
1644 "goto cond_logical;",
1646 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1647 "res = DSP_R (x) | DSP_R (y);",
1648 "goto cond_logical;",
1650 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1651 "int Sx = DSP_R (x);",
1652 "int Sx_grd = GET_DSP_GRD (x);",
1654 "res = Sx - 0x10000;",
1655 "carry = res > Sx;",
1656 "res_grd = Sx_grd - carry;",
1657 "COMPUTE_OVERFLOW;",
1659 "res &= 0xffff0000;",
1661 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1662 "int Sx = DSP_R (x);",
1663 "int Sx_grd = GET_DSP_GRD (x);",
1665 "res = Sx + 0x10000;",
1666 "carry = res < Sx;",
1667 "res_grd = Sx_grd + carry;",
1668 "COMPUTE_OVERFLOW;",
1670 "res &= 0xffff0000;",
1672 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1673 "int Sy = DSP_R (y);",
1674 "int Sy_grd = SIGN32 (Sy);",
1676 "res = Sy - 0x10000;",
1677 "carry = res > Sy;",
1678 "res_grd = Sy_grd - carry;",
1679 "COMPUTE_OVERFLOW;",
1681 "res &= 0xffff0000;",
1683 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1684 "int Sy = DSP_R (y);",
1685 "int Sy_grd = SIGN32 (Sy);",
1687 "res = Sy + 0x10000;",
1688 "carry = res < Sy;",
1689 "res_grd = Sy_grd + carry;",
1690 "COMPUTE_OVERFLOW;",
1692 "res &= 0xffff0000;",
1694 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1699 "greater_equal = 1;",
1701 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1702 "unsigned Sx = DSP_R (x);",
1703 "int Sx_grd = GET_DSP_GRD (x);",
1708 " Sx_grd = ~Sx_grd;",
1722 " if (Sx & ~0 << i)",
1730 "res_grd = SIGN32 (res);",
1735 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1736 "unsigned Sy = DSP_R (y);",
1745 " if (Sy & ~0 << i)",
1753 "res_grd = SIGN32 (res);",
1758 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1759 "int Sx = DSP_R (x);",
1760 "int Sx_grd = GET_DSP_GRD (x);",
1763 "carry = res != 0;",
1764 "res_grd = 0 - Sx_grd - carry;",
1765 "COMPUTE_OVERFLOW;",
1768 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1770 "res_grd = GET_DSP_GRD (x);",
1772 "COMPUTE_OVERFLOW;",
1775 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1776 "int Sy = DSP_R (y);",
1777 "int Sy_grd = SIGN32 (Sy);",
1780 "carry = res != 0;",
1781 "res_grd = 0 - Sy_grd - carry;",
1782 "COMPUTE_OVERFLOW;",
1785 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1787 "res_grd = SIGN32 (res);",
1789 "COMPUTE_OVERFLOW;",
1792 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1794 "res_grd = SIGN32 (res);",
1797 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1799 "res_grd = SIGN32 (res);",
1802 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1803 "if (0xa05f >> z & 1)",
1804 " RAISE_EXCEPTION (SIGILL);",
1806 " MACH = DSP_R (z);",
1809 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1810 "if (0xa05f >> z & 1)",
1811 " RAISE_EXCEPTION (SIGILL);",
1813 " MACL = DSP_R (z) = res;",
1819 /* Tables of things to put into enums for sh-opc.h */
1820 static char *nibble_type_list[] =
1855 char *arg_type_list[] =
1889 make_enum_list (name, s)
1894 printf ("typedef enum {\n");
1897 printf ("\t%s,\n", *s);
1901 printf ("} %s;\n", name);
1913 memcpy (bufa, a->code, 4);
1914 memcpy (bufa + 4, a->code + 12, 4);
1917 memcpy (bufb, b->code, 4);
1918 memcpy (bufb + 4, b->code + 12, 4);
1920 diff = strcmp (bufa, bufb);
1921 /* Stabilize the sort, so that later entries can override more general
1922 preceding entries. */
1923 return diff ? diff : a - b;
1937 qsort (tab, len, sizeof (*p), qfunc);
1945 for (p = tab; p->name; p++)
1947 printf ("%s %-30s\n", p->code, p->name);
1953 /* Convert a string of 4 binary digits into an int */
1973 static unsigned char table[1 << 16];
1975 /* Take an opcode expand all varying fields in it out and fill all the
1976 right entries in 'table' with the opcode index*/
1979 expand_opcode (shift, val, i, s)
2001 if (s[1] - '0' > 1U || !s[2] || ! s[3])
2002 expand_opcode (shift - 1, val + s[0] - '0', i, s + 1);
2003 val |= bton (s) << shift;
2004 if (s[2] == '0' || s[2] == '1')
2005 expand_opcode (shift - 4, val, i, s + 4);
2006 else if (s[2] == 'N')
2007 for (j = 0; j < 4; j++)
2008 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2009 else if (s[2] == 'x')
2010 for (j = 0; j < 4; j += 2)
2011 for (m = 0; m < 32; m++)
2013 /* Ignore illegal nopy */
2014 if ((m & 7) == 0 && m != 0)
2016 mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
2017 expand_opcode (shift - 4, val | mv | (j << shift), i,
2020 else if (s[2] == 'y')
2021 for (j = 0; j < 2; j++)
2022 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2029 while (s[digits] == s[0])
2031 for (j = 0; j < (1 << digits); j++)
2033 expand_opcode (shift - digits, val | (j << shift), i,
2039 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2040 for (j = 5; j < 16; j++)
2042 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2046 for (j = 13; j <= 15; j +=2)
2047 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2050 /* System registers mach, macl, pr: */
2051 for (j = 0; j < 3; j++)
2052 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2053 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2054 for (j = 5; j < 12; j++)
2055 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2059 val |= bton (s) << shift;
2060 for (j = 0; j < 16; j += 8)
2061 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2065 val |= bton (s) << shift;
2066 for (j = 0; j < 8; j += 4)
2067 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2071 for (j = 0; j < (1 << (shift + 4)); j++)
2079 /* Print the jump table used to index an opcode into a switch
2083 dumptable (name, size, start)
2093 printf ("unsigned char %s[%d]={\n", name, size);
2094 while (i < start + size)
2098 printf ("/* 0x%x */\n", i);
2105 printf ("%2d", table[i + j + k]);
2124 static int index = 1;
2127 for (; p->name; p++)
2130 expand_opcode (12, 0, p->index, p->code);
2134 /* Table already contains all the switch case tags for 16-bit opcode double
2135 data transfer (ddt) insns, and the switch case tag for processing parallel
2136 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2137 latter tag to represent all combinations of ppi with ddt. */
2143 for (i = 0xf000; i < 0xf400; i++)
2145 table[i + 0x800] = table[0xf800];
2152 for (; p->name; p++)
2161 printf (" /* %s %s */\n", p->name, p->code);
2162 printf (" case %d: \n", p->index);
2170 fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2182 printf (" int n = (iword >>8) & 0xf;\n");
2187 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2191 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2196 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2205 printf (" int m = (iword >>4) & 0xf;\n");
2209 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2213 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2217 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2221 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2226 printf (" int i = (iword & 0x");
2261 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2262 sextbit - 1, sextbit - 1);
2266 printf (" TB(m,n);\n");
2268 printf (" TL(m);\n");
2270 printf (" TL(n);\n");
2275 for (r = p->refs; *r; r++)
2277 if (*r == '0') printf(" CREF(0);\n");
2278 if (*r == '8') printf(" CREF(8);\n");
2279 if (*r == '9') printf(" CREF(9);\n");
2280 if (*r == 'n') printf(" CREF(n);\n");
2281 if (*r == 'm') printf(" CREF(m);\n");
2286 for (j = 0; j < MAX_NR_STUFF; j++)
2290 printf (" %s\n", p->stuff[j]);
2298 for (r = p->defs; *r; r++)
2300 if (*r == '0') printf(" CDEF(0);\n");
2301 if (*r == 'n') printf(" CDEF(n);\n");
2302 if (*r == 'm') printf(" CDEF(m);\n");
2306 printf (" break;\n");
2315 printf (" switch (jump_table[iword]) {\n");
2317 gensim_caselist (tab);
2318 gensim_caselist (movsxy_tab);
2320 printf (" default:\n");
2322 printf (" RAISE_EXCEPTION (SIGILL);\n");
2333 for (p = tab; p->name; p++)
2336 printf ("#define OPC_");
2340 if (isalpha(*s)) printf("%c", *s);
2341 if (*s == ' ') printf("_");
2342 if (*s == '@') printf("ind_");
2343 if (*s == ',') printf("_");
2346 printf(" %d\n",p->index);
2350 static int ppi_index;
2352 /* Take a ppi code, expand all varying fields in it and fill all the
2353 right entries in 'table' with the opcode index. */
2356 expand_ppi_code (val, i, s)
2368 fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n",
2372 /* The last eight bits are disregarded for the switch table. */
2390 expand_ppi_code (val, i, s);
2397 expand_ppi_code (val, ppi_index++, s);
2399 expand_ppi_code (val, i, s);
2412 for (p = ppi_tab; p->name; p++)
2414 p->index = ppi_index++;
2415 expand_ppi_code (0, p->index, p->code);
2424 printf ("#define DSR_MASK_G 0x80\n");
2425 printf ("#define DSR_MASK_Z 0x40\n");
2426 printf ("#define DSR_MASK_N 0x20\n");
2427 printf ("#define DSR_MASK_V 0x10\n");
2429 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2430 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2431 printf (" if (overflow && S) \\\n");
2433 printf (" if (res_grd & 0x80) \\\n");
2435 printf (" res = 0x80000000; \\\n");
2436 printf (" res_grd |= 0xff; \\\n");
2438 printf (" else \\\n");
2440 printf (" res = 0x7fffffff; \\\n");
2441 printf (" res_grd &= ~0xff; \\\n");
2443 printf (" overflow = 0; \\\n");
2445 printf ("} while (0)\n");
2447 printf ("#define ADD_SUB_GE \\\n");
2448 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2450 printf ("static void\n");
2451 printf ("ppi_insn (iword)\n");
2452 printf (" int iword;\n");
2454 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2455 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2456 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2457 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2458 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2459 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2461 printf (" int z;\n");
2462 printf (" int res, res_grd;\n");
2463 printf (" int carry, overflow, greater_equal;\n");
2465 printf (" switch (ppi_table[iword >> 8]) {\n");
2467 for (; p->name; p++)
2475 printf (" /* %s %s */\n", p->name, p->code);
2476 printf (" case %d: \n", p->index);
2479 for (shift = 16; *s; )
2484 printf (" int i = (iword >> 4) & 0x7f;\n");
2494 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2500 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2501 printf ("\treturn;\n");
2503 printf (" case %d: \n", p->index + 1);
2515 printf (" z = iword & 0xf;\n");
2523 else if (havedecl == 2)
2525 for (j = 0; j < MAX_NR_STUFF; j++)
2530 (havedecl == 2 ? " " : ""),
2538 printf (" if (iword & 0x200)\n");
2539 printf (" goto assign_z;\n");
2541 printf (" break;\n");
2545 printf (" default:\n");
2547 printf (" RAISE_EXCEPTION (SIGILL);\n");
2548 printf (" return;\n");
2551 printf (" DSR &= ~0xf1;\n");
2552 printf (" if (res || res_grd)\n");
2553 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2555 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2556 printf (" assign_dc:\n");
2557 printf (" switch (DSR >> 1 & 7)\n");
2559 printf (" case 0: /* Carry Mode */\n");
2560 printf (" DSR |= carry;\n");
2561 printf (" case 1: /* Negative Value Mode */\n");
2562 printf (" DSR |= res_grd >> 7 & 1;\n");
2563 printf (" case 2: /* Zero Value Mode */\n");
2564 printf (" DSR |= DSR >> 6 & 1;\n");
2565 printf (" case 3: /* Overflow mode\n");
2566 printf (" DSR |= overflow >> 4;\n");
2567 printf (" case 4: /* Signed Greater Than Mode */\n");
2568 printf (" DSR |= DSR >> 7 & 1;\n");
2569 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2570 printf (" DSR |= greater_equal >> 7;\n");
2572 printf (" assign_z:\n");
2573 printf (" if (0xa05f >> z & 1)\n");
2575 printf (" RAISE_EXCEPTION (SIGILL);\n");
2576 printf (" return;\n");
2578 printf (" DSP_R (z) = res;\n");
2579 printf (" DSP_GRD (z) = res_grd;\n");
2588 /* verify the table before anything else */
2591 for (p = tab; p->name; p++)
2593 /* check that the code field contains 16 bits */
2594 if (strlen (p->code) != 16)
2596 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2597 p->code, strlen (p->code), p->name);
2603 /* now generate the requested data */
2606 if (strcmp (av[1], "-t") == 0)
2610 else if (strcmp (av[1], "-d") == 0)
2614 else if (strcmp (av[1], "-s") == 0)
2617 dumptable ("sh_jump_table", 1 << 16, 0);
2619 memset (table, 0, sizeof table);
2620 filltable (movsxy_tab);
2622 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2624 memset (table, 0, sizeof table);
2626 dumptable ("ppi_table", 1 << 8, 0);
2628 else if (strcmp (av[1], "-x") == 0)
2631 filltable (movsxy_tab);
2634 else if (strcmp (av[1], "-p") == 0)
2641 fprintf (stderr, "Opcode table generation no longer supported.\n");