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 generates the opcode tables
34 #define MAX_NR_STUFF 20
42 char *stuff
[MAX_NR_STUFF
];
52 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
55 " UNDEF(n); /* see #ifdef PARANOID */",
59 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
63 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
65 "SET_SR_T (ult < R[n]);",
67 "SET_SR_T (T || (R[n] < ult));",
70 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
72 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
76 { "0", "", "and #<imm>,R0", "11001001i8*1....",
79 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
82 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
84 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
87 { "", "", "bf <bdisp8>", "10001011i8p1....",
89 " nia = PC + 4 + (SEXT(i) * 2);",
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
96 " nia = PC + 4 + (SEXT (i) * 2);",
98 " Delay_Slot (PC + 2);",
102 { "", "", "bra <bdisp12>", "1010i12.........",
103 "nia = PC + 4 + (SEXT12 (i) * 2);",
104 "Delay_Slot (PC + 2);",
107 { "", "n", "braf <REG_N>", "0000nnnn00100011",
108 "nia = PC + 4 + R[n];",
109 "Delay_Slot (PC + 2);",
112 { "", "", "bsr <bdisp12>", "1011i12.........",
114 "nia = PC + 4 + (SEXT12 (i) * 2);",
115 "Delay_Slot (PC + 2);",
118 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
120 "nia = PC + 4 + R[n];",
121 "Delay_Slot (PC + 2);",
124 { "", "", "bt <bdisp8>", "10001001i8p1....",
126 " nia = PC + 4 + (SEXT (i) * 2);",
131 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
133 " nia = PC + 4 + (SEXT (i) * 2);",
135 " Delay_Slot (PC + 2);",
139 { "", "", "clrmac", "0000000000101000",
144 { "", "", "clrs", "0000000001001000",
148 { "", "", "clrt", "0000000000001000",
152 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
153 "SET_SR_T (R0 == SEXT (i));",
155 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
156 "SET_SR_T (R[n] == R[m]);",
158 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
159 "SET_SR_T (R[n] >= R[m]);",
161 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
162 "SET_SR_T (R[n] > R[m]);",
164 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
165 "SET_SR_T (UR[n] > UR[m]);",
167 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
168 "SET_SR_T (UR[n] >= UR[m]);",
170 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
171 "SET_SR_T (R[n] > 0);",
173 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
174 "SET_SR_T (R[n] >= 0);",
176 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
177 "ult = R[n] ^ R[m];",
178 "SET_SR_T (((ult & 0xff000000) == 0)",
179 " | ((ult & 0xff0000) == 0)",
180 " | ((ult & 0xff00) == 0)",
181 " | ((ult & 0xff) == 0));",
184 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
185 "SET_SR_Q ((R[n] & sbit) != 0);",
186 "SET_SR_M ((R[m] & sbit) != 0);",
187 "SET_SR_T (M != Q);",
190 { "", "", "div0u", "0000000000011001",
196 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
197 "div1 (R, m, n/*, T*/);",
200 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
201 "dmul (1/*signed*/, R[n], R[m]);",
204 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
205 "dmul (0/*unsigned*/, R[n], R[m]);",
208 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
210 "SET_SR_T (R[n] == 0);",
213 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
214 "R[n] = SEXT (R[m]);",
216 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
217 "R[n] = SEXTW (R[m]);",
220 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
221 "R[n] = (R[m] & 0xff);",
223 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
224 "R[n] = (R[m] & 0xffff);",
228 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
229 "FP_UNARY (n, fabs);",
230 "/* FIXME: FR(n) &= 0x7fffffff; */",
234 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
239 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
240 "FP_CMP (n, ==, m);",
243 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
248 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
249 "if (! FPSCR_PR || n & 1)",
250 " saved_state.asregs.exception = SIGILL;",
264 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
265 "if (! FPSCR_PR || n & 1)",
266 " saved_state.asregs.exception = SIGILL;",
280 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
282 "/* FIXME: check for DP and (n & 1) == 0? */",
286 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
287 "/* FIXME: not implemented */",
288 "saved_state.asregs.exception = SIGILL;",
289 "/* FIXME: check for DP and (n & 1) == 0? */",
293 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
294 "SET_FR (n, (float)0.0);",
295 "/* FIXME: check for DP and (n & 1) == 0? */",
299 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
300 "SET_FR (n, (float)1.0);",
301 "/* FIXME: check for DP and (n & 1) == 0? */",
305 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
316 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
319 " SET_DR (n, (double)FPUL);",
322 " SET_FR (n, (float)FPUL);",
327 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
328 "SET_FR (n, FR(m) * FR(0) + FR(n));",
329 "/* FIXME: check for DP and (n & 1) == 0? */",
333 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
336 " int ni = XD_TO_XF (n);",
337 " int mi = XD_TO_XF (m);",
338 " SET_XF (ni + 0, XF (mi + 0));",
339 " SET_XF (ni + 1, XF (mi + 1));",
343 " SET_FR (n, FR (m));",
347 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
356 " WLAT (R[n], FI(m));",
360 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
369 " SET_FI(n, RLAT(R[m]));",
373 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
383 " SET_FI (n, RLAT (R[m]));",
388 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
399 " WLAT (R[n], FI(m));",
403 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
407 " RDAT (R[0]+R[m], n);",
412 " SET_FI(n, RLAT(R[0] + R[m]));",
416 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
420 " WDAT (R[0]+R[n], m);",
425 " WLAT((R[0]+R[n]), FI(m));",
429 /* sh4: See fmov instructions above for move to/from extended fp registers */
432 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
437 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
442 { "", "", "frchg", "1111101111111101",
443 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
447 { "", "", "fschg", "1111001111111101",
448 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
452 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
453 "FP_UNARY(n, sqrt);",
457 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
462 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
465 " if (DR(n) != DR(n)) /* NaN */",
466 " FPUL = 0x80000000;",
468 " FPUL = (int)DR(n);",
471 "if (FR(n) != FR(n)) /* NaN */",
472 " FPUL = 0x80000000;",
474 " FPUL = (int)FR(n);",
478 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
488 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
490 "Delay_Slot (PC + 2);",
493 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
497 " gotcall (PR, nia);",
498 "Delay_Slot (PC + 2);",
501 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
503 "/* FIXME: user mode */",
505 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
507 "/* FIXME: user mode */",
509 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
511 "/* FIXME: user mode */",
513 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
515 "/* FIXME: user mode */",
517 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
519 "/* FIXME: user mode */",
522 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
524 "/* FIXME: user mode */",
527 { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
528 "SET_Rn_BANK (0, R[n]);",
529 "/* FIXME: user mode */",
531 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
532 "SET_Rn_BANK (1, R[n]);",
533 "/* FIXME: user mode */",
535 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
536 "SET_Rn_BANK (2, R[n]);",
537 "/* FIXME: user mode */",
539 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
540 "SET_Rn_BANK (3, R[n]);",
541 "/* FIXME: user mode */",
543 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
544 "SET_Rn_BANK (4, R[n]);",
545 "/* FIXME: user mode */",
547 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
548 "SET_Rn_BANK (5, R[n]);",
549 "/* FIXME: user mode */",
551 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
552 "SET_Rn_BANK (6, R[n]);",
553 "/* FIXME: user mode */",
555 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
556 "SET_Rn_BANK (7, R[n]);",
557 "/* FIXME: user mode */",
559 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
561 "GBR = RLAT (R[n]);",
563 "/* FIXME: user mode */",
565 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
567 "SET_SR (RLAT (R[n]));",
569 "/* FIXME: user mode */",
571 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
573 "VBR = RLAT (R[n]);",
575 "/* FIXME: user mode */",
577 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
579 "SSR = RLAT (R[n]);",
581 "/* FIXME: user mode */",
583 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
585 "SPC = RLAT (R[n]);",
587 "/* FIXME: user mode */",
590 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
592 "DBR = RLAT (R[n]);",
594 "/* FIXME: user mode */",
597 { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
599 "SET_Rn_BANK (0, RLAT (R[n]));",
601 "/* FIXME: user mode */",
603 { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
605 "SET_Rn_BANK (1, RLAT (R[n]));",
607 "/* FIXME: user mode */",
609 { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
611 "SET_Rn_BANK (2, RLAT (R[n]));",
613 "/* FIXME: user mode */",
615 { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
617 "SET_Rn_BANK (3, RLAT (R[n]));",
619 "/* FIXME: user mode */",
621 { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
623 "SET_Rn_BANK (4, RLAT (R[n]));",
625 "/* FIXME: user mode */",
627 { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
629 "SET_Rn_BANK (5, RLAT (R[n]));",
631 "/* FIXME: user mode */",
633 { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
635 "SET_Rn_BANK (6, RLAT (R[n]));",
637 "/* FIXME: user mode */",
639 { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
641 "SET_Rn_BANK (7, RLAT (R[n]));",
643 "/* FIXME: user mode */",
647 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
651 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
653 "FPUL = RLAT(R[n]);",
657 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
661 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
663 "SET_FPSCR (RLAT(R[n]));",
667 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
670 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
673 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
676 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
678 "MACH = SEXT(RLAT(R[n]));",
681 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
683 "MACL = RLAT(R[n]);",
686 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
692 { "", "", "ldtlb", "0000000000111000",
693 "/* FIXME: XXX*/ abort();",
696 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
697 "trap (255,R0,memory,maskl,maskw,little_endian);",
698 "/* FIXME: mac.l support */",
701 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
702 "macw(R0,memory,n,m);",
705 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
708 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
712 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
714 "R0 = RSBAT (i + GBR);",
717 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
719 "R0 = RSBAT (i + R[m]);",
722 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
724 "R[n] = RSBAT (R0 + R[m]);",
727 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
729 "R[n] = RSBAT (R[m]);",
733 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
735 "WBAT (R[n], R[m]);",
737 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
739 "WBAT (i + GBR, R0);",
741 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
743 "WBAT (i + R[m], R0);",
745 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
747 "WBAT (R[n] + R0, R[m]);",
749 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
752 "WBAT (R[n], R[m]);",
754 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
756 "R[n] = RSBAT (R[m]);",
760 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
762 "R0 = RLAT (i + GBR);",
765 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
767 "R[n] = RLAT((PC & ~3) + 4 + i);",
770 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
772 "R[n] = RLAT (i + R[m]);",
775 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
777 "R[n] = RLAT (R0 + R[m]);",
780 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
782 "R[n] = RLAT (R[m]);",
786 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
788 "R[n] = RLAT (R[m]);",
791 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
793 "WLAT (i + GBR, R0);",
795 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
797 "WLAT (i + R[n], R[m]);",
799 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
801 "WLAT (R0 + R[n], R[m]);",
803 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
806 "WLAT (R[n], R[m]);",
808 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
810 "WLAT (R[n], R[m]);",
813 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
815 ";R0 = RSWAT (i + GBR);",
818 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
820 "R[n] = RSWAT (PC + 4 + i);",
823 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
825 "R0 = RSWAT (i + R[m]);",
828 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
830 "R[n] = RSWAT (R0 + R[m]);",
833 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
835 "R[n] = RSWAT (R[m]);",
839 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
841 "R[n] = RSWAT (R[m]);",
844 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
846 "WWAT (i + GBR, R0);",
848 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
850 "WWAT (i + R[m], R0);",
852 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
854 "WWAT (R0 + R[n], R[m]);",
856 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
859 "WWAT (R[n], R[m]);",
861 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
863 "WWAT (R[n], R[m]);",
866 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
867 "R0 = ((i + 4 + PC) & ~0x3);",
870 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
871 "/* FIXME: Not implemented */",
872 "saved_state.asregs.exception = SIGILL;",
875 { "n", "", "movt <REG_N>", "0000nnnn00101001",
879 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
880 "MACL = ((int)R[n]) * ((int)R[m]);",
883 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
884 "MACL = R[n] * R[m];",
888 /* muls.w - see muls */
889 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
890 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
893 /* mulu.w - see mulu */
894 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
895 "MACL = (((unsigned int)(unsigned short)R[n])",
896 " * ((unsigned int)(unsigned short)R[m]));",
899 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
903 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
905 "SET_SR_T (ult > 0);",
906 "R[n] = ult - R[m];",
907 "SET_SR_T (T || (R[n] > ult));",
910 { "", "", "nop", "0000000000001001",
914 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
918 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
919 "/* FIXME: Not implemented */",
920 "saved_state.asregs.exception = SIGILL;",
923 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
924 "/* FIXME: Not implemented */",
925 "saved_state.asregs.exception = SIGILL;",
928 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
929 "RSBAT (R[n]); /* Take exceptions like byte load. */",
930 "/* FIXME: Cache not implemented */",
933 { "0", "", "or #<imm>,R0", "11001011i8*1....",
936 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
939 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
941 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
944 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
945 "/* Except for the effect on the cache - which is not simulated -",
946 " this is like a nop. */",
949 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
951 "R[n] = (R[n] << 1) | T;",
955 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
957 "R[n] = (UR[n] >> 1) | (T << 31);",
961 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
962 "SET_SR_T (R[n] < 0);",
967 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
968 "SET_SR_T (R[n] & 1);",
969 "R[n] = UR[n] >> 1;",
970 "R[n] |= (T << 31);",
973 { "", "", "rte", "0000000000101011",
977 "nia = RLAT (R[15]) + 2;",
979 "SET_SR (RLAT (R[15]) & 0x3f3);",
981 "Delay_Slot (PC + 2);",
985 "Delay_Slot (PC + 2);",
989 { "", "", "rts", "0000000000001011",
991 "Delay_Slot (PC + 2);",
994 { "", "", "sets", "0000000001011000",
998 { "", "", "sett", "0000000000011000",
1002 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1003 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
1006 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1007 "SET_SR_T (R[n] < 0);",
1011 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1012 "SET_SR_T (R[n] & 1);",
1013 "R[n] = R[n] >> 1;",
1016 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1017 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
1020 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1021 "SET_SR_T (R[n] < 0);",
1025 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1028 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1031 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1035 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1036 "SET_SR_T (R[n] & 1);",
1037 "R[n] = UR[n] >> 1;",
1040 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1041 "R[n] = UR[n] >> 2;",
1043 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1044 "R[n] = UR[n] >> 8;",
1046 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1047 "R[n] = UR[n] >> 16;",
1050 { "", "", "sleep", "0000000000011011",
1051 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
1055 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
1058 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
1059 "R[n] = GET_SR ();",
1061 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
1064 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
1067 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
1071 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1074 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1078 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
1079 "R[n] = Rn_BANK (0);",
1081 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
1082 "R[n] = Rn_BANK (1);",
1084 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
1085 "R[n] = Rn_BANK (2);",
1087 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
1088 "R[n] = Rn_BANK (3);",
1090 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
1091 "R[n] = Rn_BANK (4);",
1093 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
1094 "R[n] = Rn_BANK (5);",
1096 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
1097 "R[n] = Rn_BANK (6);",
1099 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
1100 "R[n] = Rn_BANK (7);",
1102 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
1105 "WLAT (R[n], GBR);;",
1107 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
1110 "WLAT (R[n], GET_SR());",
1112 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
1115 "WLAT (R[n], VBR);",
1117 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
1120 "WLAT (R[n], SSR);",
1122 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
1125 "WLAT (R[n], SPC);",
1128 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1131 "WLAT (R[n], SGR);",
1133 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1136 "WLAT (R[n], DBR);",
1139 { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
1142 "WLAT (R[n], Rn_BANK (0));",
1144 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
1147 "WLAT (R[n], Rn_BANK (1));",
1149 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
1152 "WLAT (R[n], Rn_BANK (2));",
1154 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
1157 "WLAT (R[n], Rn_BANK (3));",
1159 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
1162 "WLAT (R[n], Rn_BANK (4));",
1164 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
1167 "WLAT (R[n], Rn_BANK (5));",
1169 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1172 "WLAT (R[n], Rn_BANK (6));",
1174 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1177 "WLAT (R[n], Rn_BANK (7));",
1181 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1185 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1188 "WLAT (R[n], FPUL);",
1191 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1192 "R[n] = GET_FPSCR ();",
1195 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1198 "WLAT (R[n], GET_FPSCR ());",
1201 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1204 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1207 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1210 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1213 "WLAT (R[n], MACH);",
1215 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1218 "WLAT (R[n], MACL);",
1220 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1226 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1230 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1232 "SET_SR_T (ult > R[n]);",
1233 "R[n] = ult - R[m];",
1234 "SET_SR_T (T || (R[n] > ult));",
1237 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1238 "ult = R[n] - R[m];",
1239 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1243 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1244 "R[n] = ((R[m] & 0xffff0000)",
1245 " | ((R[m] << 8) & 0xff00)",
1246 " | ((R[m] >> 8) & 0x00ff));",
1248 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1249 "R[n] = (((R[m] << 16) & 0xffff0000)",
1250 " | ((R[m] >> 16) & 0x00ffff));",
1253 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1255 "ult = RBAT(R[n]);",
1256 "SET_SR_T (ult == 0);",
1257 "WBAT(R[n],ult|0x80);",
1260 { "0", "", "trapa #<imm>", "11000011i8*1....",
1263 "long imm = 0xff & i;",
1266 "if (i<20||i==34||i==0xc3)",
1267 " trap(i,R,memory,maskl,maskw,little_endian);",
1270 " WLAT(R[15],GET_SR());",
1272 " WLAT(R[15],PC+2);",
1273 " PC=RLAT(VBR+(imm<<2))-2;",
1279 " trap (i, R, memory, maskl, maskw, little_endian);",
1281 "else if (i < 20 || i==34 || i==0xc3)",
1282 " trap (i, R, memory, maskl, maskw, little_endian);",
1283 "else if (!SR_BL) {",
1284 " /* FIXME: TRA = (imm << 2); */",
1287 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1288 " /* FIXME: EXPEVT = 0x00000160; */",
1289 " nia = VBR + 0x00000100;",
1294 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1295 "SET_SR_T ((R[n] & R[m]) == 0);",
1297 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1298 "SET_SR_T ((R0 & i) == 0);",
1300 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1302 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1305 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1308 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1311 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1313 "ult = RBAT (GBR+R0);",
1315 "WBAT (GBR + R0, ult);",
1318 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1319 "R[n] = (((R[n] >> 16) & 0xffff)",
1320 " | ((R[m] << 16) & 0xffff0000));",
1324 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1325 "divl(0,R[n],R[m]);",
1327 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1328 "divl(0,R[n],R[m]);",
1334 /* Tables of things to put into enums for sh-opc.h */
1335 static char *nibble_type_list
[] =
1370 char *arg_type_list
[] =
1404 make_enum_list (name
, s
)
1409 printf ("typedef enum {\n");
1412 printf ("\t%s,\n", *s
);
1416 printf ("} %s;\n", name
);
1426 memcpy (bufa
, a
->code
, 4);
1427 memcpy (bufa
+ 4, a
->code
+ 12, 4);
1430 memcpy (bufb
, b
->code
, 4);
1431 memcpy (bufb
+ 4, b
->code
+ 12, 4);
1433 return (strcmp (bufa
, bufb
));
1447 qsort (tab
, len
, sizeof (*p
), qfunc
);
1451 printonmatch (ptr
, a
, rep
)
1457 if (strncmp (*ptr
, a
, l
) == 0)
1477 while (*n
&& *n
!= ' ')
1492 while (*p
== ',' || *p
== ' ')
1494 printonmatch (&p
, "#<imm>", "A_IMM");
1495 printonmatch (&p
, "R0", "A_R0");
1496 printonmatch (&p
, "<REG_N>", "A_REG_N");
1497 printonmatch (&p
, "@<REG_N>+", "A_INC_N");
1498 printonmatch (&p
, "@<REG_N>", "A_IND_N");
1499 printonmatch (&p
, "@-<REG_N>", "A_DEC_N");
1500 printonmatch (&p
, "<REG_M>", " A_REG_M");
1501 printonmatch (&p
, "@<REG_M>+", "A_INC_M");
1502 printonmatch (&p
, "@<REG_M>", "A_IND_M");
1503 printonmatch (&p
, "@-<REG_M>", "A_DEC_M");
1504 printonmatch (&p
, "@(<disp>,PC)", "A_DISP_PC");
1505 printonmatch (&p
, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1506 printonmatch (&p
, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1507 printonmatch (&p
, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1508 printonmatch (&p
, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1509 printonmatch (&p
, "@(<disp>,GBR)", "A_DISP_GBR");
1510 printonmatch (&p
, "@(R0,GBR)", "A_R0_GBR");
1511 printonmatch (&p
, "<bdisp8>", "A_BDISP8");
1512 printonmatch (&p
, "<bdisp12>", "A_BDISP12");
1513 printonmatch (&p
, "SR", "A_SR");
1514 printonmatch (&p
, "GBR", "A_GBR");
1515 printonmatch (&p
, "VBR", "A_VBR");
1516 printonmatch (&p
, "SSR", "A_SSR");
1517 printonmatch (&p
, "SPC", "A_SPC");
1518 printonmatch (&p
, "MACH", "A_MACH");
1519 printonmatch (&p
, "MACL", "A_MACL");
1520 printonmatch (&p
, "PR", "A_PR");
1528 printonmatch (&p
, "0000", "HEX_0");
1529 printonmatch (&p
, "0001", "HEX_1");
1530 printonmatch (&p
, "0010", "HEX_2");
1531 printonmatch (&p
, "0011", "HEX_3");
1532 printonmatch (&p
, "0100", "HEX_4");
1533 printonmatch (&p
, "0101", "HEX_5");
1534 printonmatch (&p
, "0110", "HEX_6");
1535 printonmatch (&p
, "0111", "HEX_7");
1537 printonmatch (&p
, "1000", "HEX_8");
1538 printonmatch (&p
, "1001", "HEX_9");
1539 printonmatch (&p
, "1010", "HEX_A");
1540 printonmatch (&p
, "1011", "HEX_B");
1541 printonmatch (&p
, "1100", "HEX_C");
1542 printonmatch (&p
, "1101", "HEX_D");
1543 printonmatch (&p
, "1110", "HEX_E");
1544 printonmatch (&p
, "1111", "HEX_F");
1545 printonmatch (&p
, "i8*1....", "IMM_8");
1546 printonmatch (&p
, "i4*1", "IMM_4");
1547 printonmatch (&p
, "i8p4....", "PCRELIMM_8BY4");
1548 printonmatch (&p
, "i8p2....", "PCRELIMM_8BY2");
1549 printonmatch (&p
, "i8*2....", "IMM_8BY2");
1550 printonmatch (&p
, "i4*2", "IMM_4BY2");
1551 printonmatch (&p
, "i8*4....", "IMM_8BY4");
1552 printonmatch (&p
, "i4*4", "IMM_4BY4");
1553 printonmatch (&p
, "i12.........", "BRANCH_12");
1554 printonmatch (&p
, "i8p1....", "BRANCH_8");
1555 printonmatch (&p
, "nnnn", "REG_N");
1556 printonmatch (&p
, "mmmm", "REG_M");
1567 for (p
= tab
; p
->name
; p
++)
1569 printf ("%s %-30s\n", p
->code
, p
->name
);
1580 make_enum_list ("sh_nibble_type", nibble_type_list
);
1581 make_enum_list ("sh_arg_type", arg_type_list
);
1583 printf ("typedef struct {\n");
1584 printf ("char *name;\n");
1585 printf ("sh_arg_type arg[3];\n");
1586 printf ("sh_nibble_type nibbles[4];\n");
1587 printf ("} sh_opcode_info;\n");
1588 printf ("#ifdef DEFINE_TABLE\n");
1589 printf ("sh_opcode_info sh_table[]={\n");
1590 for (p
= tab
; p
->name
; p
++)
1592 printf ("\n/* %s %-20s*/", p
->code
, p
->name
);
1596 printf ("#endif\n");
1604 /* Convert a string of 4 binary digits into an int */
1624 static unsigned char table
[1 << 16];
1626 /* Take an opcode expand all varying fields in it out and fill all the
1627 right entries in 'table' with the opcode index*/
1630 expand_opcode (shift
, val
, i
, s
)
1654 expand_opcode (shift
- 4, val
| (n
<< shift
), i
, s
+ 4);
1660 for (j
= 0; j
< 16; j
++)
1662 expand_opcode (shift
- 4, val
| (j
<< shift
), i
, s
+ 4);
1668 for (j
= 0; j
< (1 << (shift
+ 4)); j
++)
1676 /* Print the jump table used to index an opcode into a switch
1691 printf ("unsigned char sh_jump_table%x[%d]={\n", i
, lump
);
1698 printf ("%2d", table
[i
+ j
+ k
]);
1721 for (p
= tab
; p
->name
; p
++)
1724 expand_opcode (12, 0, p
->index
, p
->code
);
1735 printf (" switch (jump_table[iword]) {\n");
1737 for (p
= tab
; p
->name
; p
++)
1745 printf (" /* %s %s */\n", p
->name
, p
->code
);
1746 printf (" case %d: \n", p
->index
);
1759 printf (" int n = (iword >>8) & 0xf;\n");
1764 printf (" int m = (iword >>4) & 0xf;\n");
1771 printf (" int i = (iword & 0x");
1806 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1807 sextbit
- 1, sextbit
- 1);
1811 printf (" TB(m,n);\n");
1813 printf (" TL(m);\n");
1815 printf (" TL(n);\n");
1820 for (r
= p
->refs
; *r
; r
++)
1822 if (*r
== '0') printf(" CREF(0);\n");
1823 if (*r
== 'n') printf(" CREF(n);\n");
1824 if (*r
== 'm') printf(" CREF(m);\n");
1829 for (j
= 0; j
< MAX_NR_STUFF
; j
++)
1833 printf (" %s\n", p
->stuff
[j
]);
1841 for (r
= p
->defs
; *r
; r
++)
1843 if (*r
== '0') printf(" CDEF(0);\n");
1844 if (*r
== 'n') printf(" CDEF(n);\n");
1845 if (*r
== 'm') printf(" CDEF(m);\n");
1849 printf (" break;\n");
1852 printf (" default:\n");
1854 printf (" saved_state.asregs.exception = SIGILL;\n");
1866 for (p
= tab
; p
->name
; p
++)
1869 printf ("#define OPC_");
1873 if (isalpha(*s
)) printf("%c", *s
);
1874 if (*s
== ' ') printf("_");
1875 if (*s
== '@') printf("ind_");
1876 if (*s
== ',') printf("_");
1879 printf(" %d\n",p
->index
);
1888 /* verify the table before anything else */
1891 for (p
= tab
; p
->name
; p
++)
1893 /* check that the code field contains 16 bits */
1894 if (strlen (p
->code
) != 16)
1896 fprintf (stderr
, "Code `%s' length wrong (%d) for `%s'\n",
1897 p
->code
, strlen (p
->code
), p
->name
);
1903 /* now generate the requested data */
1906 if (strcmp (av
[1], "-t") == 0)
1910 else if (strcmp (av
[1], "-d") == 0)
1914 else if (strcmp (av
[1], "-s") == 0)
1920 else if (strcmp (av
[1], "-x") == 0)