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", "1111eeee11111101",
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 static unsigned char table
[1 << 16];
1955 /* Take an opcode, expand all varying fields in it out and fill all the
1956 right entries in 'table' with the opcode index. */
1959 expand_opcode (val
, i
, s
)
1975 fprintf (stderr
, "expand_opcode: illegal char '%c'\n", s
[0]);
1979 /* Consume an arbitrary number of ones and zeros. */
1981 j
= (j
<< 1) + (s
[m
++] - '0');
1982 } while (s
[m
] == '0' || s
[m
] == '1');
1983 expand_opcode ((val
<< m
) | j
, i
, s
+ m
);
1986 case 'N': /* NN -- four-way fork */
1987 for (j
= 0; j
< 4; j
++)
1988 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
1990 case 'x': /* xx -- 2-way fork */
1991 /* Cross-breeding with movy moved to separate function. */
1992 for (j
= 0; j
< 4; j
+= 2)
1993 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
1995 case 'y': /* yy -- two-way fork */
1996 for (j
= 0; j
< 2; j
++)
1997 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
1999 case 'i': /* eg. "i8*1" */
2000 case '.': /* "...." is a wildcard */
2003 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2004 for (j
= 0; j
< 16; j
++)
2005 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2008 /* eeee -- even numbered register:
2010 for (j
= 0; j
< 15; j
+= 2)
2011 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2014 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2015 MMMM -- 10-way fork */
2016 expand_opcode ((val
<< 4) | 5, i
, s
+ 4);
2017 for (j
= 7; j
< 16; j
++)
2018 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2022 GGGG -- two-way fork */
2023 for (j
= 13; j
<= 15; j
+=2)
2024 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2027 /* ssss -- 10-way fork */
2028 /* System registers mach, macl, pr: */
2029 for (j
= 0; j
< 3; j
++)
2030 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2031 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2032 for (j
= 5; j
< 12; j
++)
2033 expand_opcode ((val
<< 4) | j
, i
, s
+ 4);
2037 /* XX, aa -- two-way fork */
2038 for (j
= 0; j
< 4; j
+= 2)
2039 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
2043 /* YY, AA -- two-way fork */
2044 for (j
= 0; j
< 2; j
++)
2045 expand_opcode ((val
<< 2) | j
, i
, s
+ 2);
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 (0, p
->index
, p
->code
);
2106 /* Table already contains 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
++)
2116 if ((i
& 3) == 0 && (i
& 12) != 0 && table
[i
] != 0)
2118 /* A movx insn, which needs to be filled out with the
2119 corresponding movy insns. This used to be done in
2123 for (m
= 0; m
< 32; m
++)
2125 /* Ignore illegal nopy */
2126 if ((m
& 7) == 0 && m
!= 0)
2128 mv
= m
& 3 | (m
& 4) << 2 | (m
& 8) << 3 | (m
& 16) << 4;
2129 table
[i
| mv
] = table
[i
];
2133 for (i
= 0xf000; i
< 0xf400; i
++)
2135 table
[i
+ 0x800] = table
[0xf800];
2142 for (; p
->name
; p
++)
2151 printf (" /* %s %s */\n", p
->name
, p
->code
);
2152 printf (" case %d: \n", p
->index
);
2160 fprintf (stderr
, "gencode/gensim_caselist: illegal char '%c'\n",
2173 printf (" int n = (iword >> 8) & 0xf;\n");
2178 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2182 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2187 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2196 printf (" int m = (iword >> 4) & 0xf;\n");
2200 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2204 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2208 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2212 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2217 printf (" int i = (iword & 0x");
2252 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2253 sextbit
- 1, sextbit
- 1);
2257 printf (" TB(m,n);\n");
2259 printf (" TL(m);\n");
2261 printf (" TL(n);\n");
2266 for (r
= p
->refs
; *r
; r
++)
2268 if (*r
== '0') printf(" CREF(0);\n");
2269 if (*r
== '8') printf(" CREF(8);\n");
2270 if (*r
== '9') printf(" CREF(9);\n");
2271 if (*r
== 'n') printf(" CREF(n);\n");
2272 if (*r
== 'm') printf(" CREF(m);\n");
2277 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2281 printf (" %s\n", p
->stuff
[j
]);
2289 for (r
= p
->defs
; *r
; r
++)
2291 if (*r
== '0') printf(" CDEF(0);\n");
2292 if (*r
== 'n') printf(" CDEF(n);\n");
2293 if (*r
== 'm') printf(" CDEF(m);\n");
2297 printf (" break;\n");
2306 printf (" switch (jump_table[iword]) {\n");
2308 gensim_caselist (tab
);
2309 gensim_caselist (movsxy_tab
);
2311 printf (" default:\n");
2313 printf (" RAISE_EXCEPTION (SIGILL);\n");
2324 for (p
= tab
; p
->name
; p
++)
2327 printf ("#define OPC_");
2331 if (isalpha(*s
)) printf("%c", *s
);
2332 if (*s
== ' ') printf("_");
2333 if (*s
== '@') printf("ind_");
2334 if (*s
== ',') printf("_");
2337 printf(" %d\n",p
->index
);
2341 static int ppi_index
;
2343 /* Take a ppi code, expand all varying fields in it and fill all the
2344 right entries in 'table' with the opcode index. */
2347 expand_ppi_code (val
, i
, s
)
2359 fprintf (stderr
, "gencode/expand_ppi_code: Illegal char '%c'\n",
2363 /* The last eight bits are disregarded for the switch table. */
2381 expand_ppi_code (val
, i
, s
);
2388 expand_ppi_code (val
, ppi_index
++, s
);
2390 expand_ppi_code (val
, i
, s
);
2403 for (p
= ppi_tab
; p
->name
; p
++)
2405 p
->index
= ppi_index
++;
2406 expand_ppi_code (0, p
->index
, p
->code
);
2415 printf ("#define DSR_MASK_G 0x80\n");
2416 printf ("#define DSR_MASK_Z 0x40\n");
2417 printf ("#define DSR_MASK_N 0x20\n");
2418 printf ("#define DSR_MASK_V 0x10\n");
2420 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2421 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2422 printf (" if (overflow && S) \\\n");
2424 printf (" if (res_grd & 0x80) \\\n");
2426 printf (" res = 0x80000000; \\\n");
2427 printf (" res_grd |= 0xff; \\\n");
2429 printf (" else \\\n");
2431 printf (" res = 0x7fffffff; \\\n");
2432 printf (" res_grd &= ~0xff; \\\n");
2434 printf (" overflow = 0; \\\n");
2436 printf ("} while (0)\n");
2438 printf ("#define ADD_SUB_GE \\\n");
2439 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2441 printf ("static void\n");
2442 printf ("ppi_insn (iword)\n");
2443 printf (" int iword;\n");
2445 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2446 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2447 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2448 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2449 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2450 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2452 printf (" int z;\n");
2453 printf (" int res, res_grd;\n");
2454 printf (" int carry, overflow, greater_equal;\n");
2456 printf (" switch (ppi_table[iword >> 8]) {\n");
2458 for (; p
->name
; p
++)
2466 printf (" /* %s %s */\n", p
->name
, p
->code
);
2467 printf (" case %d: \n", p
->index
);
2470 for (shift
= 16; *s
; )
2475 printf (" int i = (iword >> 4) & 0x7f;\n");
2485 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2491 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2492 printf ("\treturn;\n");
2494 printf (" case %d: \n", p
->index
+ 1);
2506 printf (" z = iword & 0xf;\n");
2514 else if (havedecl
== 2)
2516 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
2521 (havedecl
== 2 ? " " : ""),
2529 printf (" if (iword & 0x200)\n");
2530 printf (" goto assign_z;\n");
2532 printf (" break;\n");
2536 printf (" default:\n");
2538 printf (" RAISE_EXCEPTION (SIGILL);\n");
2539 printf (" return;\n");
2542 printf (" DSR &= ~0xf1;\n");
2543 printf (" if (res || res_grd)\n");
2544 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2546 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2547 printf (" assign_dc:\n");
2548 printf (" switch (DSR >> 1 & 7)\n");
2550 printf (" case 0: /* Carry Mode */\n");
2551 printf (" DSR |= carry;\n");
2552 printf (" case 1: /* Negative Value Mode */\n");
2553 printf (" DSR |= res_grd >> 7 & 1;\n");
2554 printf (" case 2: /* Zero Value Mode */\n");
2555 printf (" DSR |= DSR >> 6 & 1;\n");
2556 printf (" case 3: /* Overflow mode\n");
2557 printf (" DSR |= overflow >> 4;\n");
2558 printf (" case 4: /* Signed Greater Than Mode */\n");
2559 printf (" DSR |= DSR >> 7 & 1;\n");
2560 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2561 printf (" DSR |= greater_equal >> 7;\n");
2563 printf (" assign_z:\n");
2564 printf (" if (0xa05f >> z & 1)\n");
2566 printf (" RAISE_EXCEPTION (SIGILL);\n");
2567 printf (" return;\n");
2569 printf (" DSP_R (z) = res;\n");
2570 printf (" DSP_GRD (z) = res_grd;\n");
2579 /* verify the table before anything else */
2582 for (p
= tab
; p
->name
; p
++)
2584 /* check that the code field contains 16 bits */
2585 if (strlen (p
->code
) != 16)
2587 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
2588 p
->code
, strlen (p
->code
), p
->name
);
2594 /* now generate the requested data */
2597 if (strcmp (av
[1], "-t") == 0)
2601 else if (strcmp (av
[1], "-d") == 0)
2605 else if (strcmp (av
[1], "-s") == 0)
2608 dumptable ("sh_jump_table", 1 << 16, 0);
2610 memset (table
, 0, sizeof table
);
2611 filltable (movsxy_tab
);
2612 expand_ppi_movxy ();
2613 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2615 memset (table
, 0, sizeof table
);
2617 dumptable ("ppi_table", 1 << 8, 0);
2619 else if (strcmp (av
[1], "-x") == 0)
2622 filltable (movsxy_tab
);
2625 else if (strcmp (av
[1], "-p") == 0)
2632 fprintf (stderr
, "Opcode table generation no longer supported.\n");
This page took 0.119172 seconds and 5 git commands to generate.