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;",
254 " *(float *)buf = DR(n);",
255 " FPUL = *(int *)buf;",
260 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
261 "if (! FPSCR_PR || n & 1)",
262 " saved_state.asregs.exception = SIGILL;",
266 " *(int *)buf = FPUL;",
267 " SET_DR(n, *(float *)buf);",
272 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
274 "/* FIXME: check for DP and (n & 1) == 0? */",
278 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
279 "/* FIXME: not implemented */",
280 "saved_state.asregs.exception = SIGILL;",
281 "/* FIXME: check for DP and (n & 1) == 0? */",
285 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
286 "SET_FR (n, (float)0.0);",
287 "/* FIXME: check for DP and (n & 1) == 0? */",
291 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
292 "SET_FR (n, (float)1.0);",
293 "/* FIXME: check for DP and (n & 1) == 0? */",
297 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
299 "*(float *)buf = FR(n);",
300 "FPUL = *(int *)buf;",
304 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
307 " SET_DR (n, (double)FPUL);",
310 " SET_FR (n, (float)FPUL);",
315 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
316 "SET_FR (n, FR(m) * FR(0) + FR(n));",
317 "/* FIXME: check for DP and (n & 1) == 0? */",
321 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
324 " int ni = XD_TO_XF (n);",
325 " int mi = XD_TO_XF (m);",
326 " SET_XF (ni + 0, XF (mi + 0));",
327 " SET_XF (ni + 1, XF (mi + 1));",
331 " SET_FR (n, FR (m));",
335 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
344 " WLAT (R[n], FI(m));",
348 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
357 " SET_FI(n, RLAT(R[m]));",
361 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
371 " SET_FI (n, RLAT (R[m]));",
376 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
387 " WLAT (R[n], FI(m));",
391 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
395 " RDAT (R[0]+R[m], n);",
400 " SET_FI(n, RLAT(R[0] + R[m]));",
404 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
408 " WDAT (R[0]+R[n], m);",
413 " WLAT((R[0]+R[n]), FI(m));",
417 /* sh4: See fmov instructions above for move to/from extended fp registers */
420 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
425 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
430 { "", "", "frchg", "1111101111111101",
431 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
435 { "", "", "fschg", "1111001111111101",
436 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
440 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
441 "FP_UNARY(n, sqrt);",
445 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
450 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
453 " if (DR(n) != DR(n)) /* NaN */",
454 " FPUL = 0x80000000;",
456 " FPUL = (int)DR(n);",
459 "if (FR(n) != FR(n)) /* NaN */",
460 " FPUL = 0x80000000;",
462 " FPUL = (int)FR(n);",
466 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
468 "*(int *)buf = FPUL;",
469 "SET_FR (n, *(float *)buf);",
472 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
474 "Delay_Slot (PC + 2);",
477 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
481 " gotcall (PR, nia);",
482 "Delay_Slot (PC + 2);",
485 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
487 "/* FIXME: user mode */",
489 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
491 "/* FIXME: user mode */",
493 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
495 "/* FIXME: user mode */",
497 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
499 "/* FIXME: user mode */",
501 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
503 "/* FIXME: user mode */",
506 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
508 "/* FIXME: user mode */",
511 { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
512 "SET_Rn_BANK (0, R[n]);",
513 "/* FIXME: user mode */",
515 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
516 "SET_Rn_BANK (1, R[n]);",
517 "/* FIXME: user mode */",
519 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
520 "SET_Rn_BANK (2, R[n]);",
521 "/* FIXME: user mode */",
523 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
524 "SET_Rn_BANK (3, R[n]);",
525 "/* FIXME: user mode */",
527 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
528 "SET_Rn_BANK (4, R[n]);",
529 "/* FIXME: user mode */",
531 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
532 "SET_Rn_BANK (5, R[n]);",
533 "/* FIXME: user mode */",
535 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
536 "SET_Rn_BANK (6, R[n]);",
537 "/* FIXME: user mode */",
539 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
540 "SET_Rn_BANK (7, R[n]);",
541 "/* FIXME: user mode */",
543 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
545 "GBR = RLAT (R[n]);",
547 "/* FIXME: user mode */",
549 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
551 "SET_SR (RLAT (R[n]));",
553 "/* FIXME: user mode */",
555 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
557 "VBR = RLAT (R[n]);",
559 "/* FIXME: user mode */",
561 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
563 "SSR = RLAT (R[n]);",
565 "/* FIXME: user mode */",
567 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
569 "SPC = RLAT (R[n]);",
571 "/* FIXME: user mode */",
574 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
576 "DBR = RLAT (R[n]);",
578 "/* FIXME: user mode */",
581 { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
583 "SET_Rn_BANK (0, RLAT (R[n]));",
585 "/* FIXME: user mode */",
587 { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
589 "SET_Rn_BANK (1, RLAT (R[n]));",
591 "/* FIXME: user mode */",
593 { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
595 "SET_Rn_BANK (2, RLAT (R[n]));",
597 "/* FIXME: user mode */",
599 { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
601 "SET_Rn_BANK (3, RLAT (R[n]));",
603 "/* FIXME: user mode */",
605 { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
607 "SET_Rn_BANK (4, RLAT (R[n]));",
609 "/* FIXME: user mode */",
611 { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
613 "SET_Rn_BANK (5, RLAT (R[n]));",
615 "/* FIXME: user mode */",
617 { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
619 "SET_Rn_BANK (6, RLAT (R[n]));",
621 "/* FIXME: user mode */",
623 { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
625 "SET_Rn_BANK (7, RLAT (R[n]));",
627 "/* FIXME: user mode */",
631 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
635 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
637 "FPUL = RLAT(R[n]);",
641 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
645 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
647 "SET_FPSCR (RLAT(R[n]));",
651 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
654 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
657 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
660 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
662 "MACH = SEXT(RLAT(R[n]));",
665 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
667 "MACL = RLAT(R[n]);",
670 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
676 { "", "", "ldtlb", "0000000000111000",
677 "/* FIXME: XXX*/ abort();",
680 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
681 "trap (255,R0,memory,maskl,maskw,little_endian);",
682 "/* FIXME: mac.l support */",
685 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
686 "macw(R0,memory,n,m);",
689 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
692 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
696 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
698 "R0 = RSBAT (i + GBR);",
701 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
703 "R0 = RSBAT (i + R[m]);",
706 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
708 "R[n] = RSBAT (R0 + R[m]);",
711 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
713 "R[n] = RSBAT (R[m]);",
717 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
719 "WBAT (R[n], R[m]);",
721 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
723 "WBAT (i + GBR, R0);",
725 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
727 "WBAT (i + R[m], R0);",
729 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
731 "WBAT (R[n] + R0, R[m]);",
733 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
736 "WBAT (R[n], R[m]);",
738 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
740 "R[n] = RSBAT (R[m]);",
744 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
746 "R0 = RLAT (i + GBR);",
749 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
751 "R[n] = RLAT((PC & ~3) + 4 + i);",
754 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
756 "R[n] = RLAT (i + R[m]);",
759 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
761 "R[n] = RLAT (R0 + R[m]);",
764 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
766 "R[n] = RLAT (R[m]);",
770 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
772 "R[n] = RLAT (R[m]);",
775 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
777 "WLAT (i + GBR, R0);",
779 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
781 "WLAT (i + R[n], R[m]);",
783 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
785 "WLAT (R0 + R[n], R[m]);",
787 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
790 "WLAT (R[n], R[m]);",
792 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
794 "WLAT (R[n], R[m]);",
797 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
799 ";R0 = RSWAT (i + GBR);",
802 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
804 "R[n] = RSWAT (PC + 4 + i);",
807 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
809 "R0 = RSWAT (i + R[m]);",
812 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
814 "R[n] = RSWAT (R0 + R[m]);",
817 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
819 "R[n] = RSWAT (R[m]);",
823 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
825 "R[n] = RSWAT (R[m]);",
828 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
830 "WWAT (i + GBR, R0);",
832 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
834 "WWAT (i + R[m], R0);",
836 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
838 "WWAT (R0 + R[n], R[m]);",
840 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
843 "WWAT (R[n], R[m]);",
845 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
847 "WWAT (R[n], R[m]);",
850 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
851 "R0 = ((i + 4 + PC) & ~0x3);",
854 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
855 "/* FIXME: Not implemented */",
856 "saved_state.asregs.exception = SIGILL;",
859 { "n", "", "movt <REG_N>", "0000nnnn00101001",
863 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
864 "MACL = ((int)R[n]) * ((int)R[m]);",
867 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
868 "MACL = R[n] * R[m];",
872 /* muls.w - see muls */
873 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
874 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
877 /* mulu.w - see mulu */
878 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
879 "MACL = (((unsigned int)(unsigned short)R[n])",
880 " * ((unsigned int)(unsigned short)R[m]));",
883 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
887 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
889 "SET_SR_T (ult > 0);",
890 "R[n] = ult - R[m];",
891 "SET_SR_T (T || (R[n] > ult));",
894 { "", "", "nop", "0000000000001001",
898 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
902 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
903 "/* FIXME: Not implemented */",
904 "saved_state.asregs.exception = SIGILL;",
907 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
908 "/* FIXME: Not implemented */",
909 "saved_state.asregs.exception = SIGILL;",
912 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
913 "RSBAT (R[n]); /* Take exceptions like byte load. */",
914 "/* FIXME: Cache not implemented */",
917 { "0", "", "or #<imm>,R0", "11001011i8*1....",
920 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
923 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
925 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
928 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
929 "/* Except for the effect on the cache - which is not simulated -",
930 " this is like a nop. */",
933 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
935 "R[n] = (R[n] << 1) | T;",
939 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
941 "R[n] = (UR[n] >> 1) | (T << 31);",
945 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
946 "SET_SR_T (R[n] < 0);",
951 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
952 "SET_SR_T (R[n] & 1);",
953 "R[n] = UR[n] >> 1;",
954 "R[n] |= (T << 31);",
957 { "", "", "rte", "0000000000101011",
961 "nia = RLAT (R[15]) + 2;",
963 "SET_SR (RLAT (R[15]) & 0x3f3);",
965 "Delay_Slot (PC + 2);",
969 "Delay_Slot (PC + 2);",
973 { "", "", "rts", "0000000000001011",
975 "Delay_Slot (PC + 2);",
978 { "", "", "sets", "0000000001011000",
982 { "", "", "sett", "0000000000011000",
986 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
987 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
990 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
991 "SET_SR_T (R[n] < 0);",
995 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
996 "SET_SR_T (R[n] & 1);",
1000 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1001 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
1004 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1005 "SET_SR_T (R[n] < 0);",
1009 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1012 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1015 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1019 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1020 "SET_SR_T (R[n] & 1);",
1021 "R[n] = UR[n] >> 1;",
1024 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1025 "R[n] = UR[n] >> 2;",
1027 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1028 "R[n] = UR[n] >> 8;",
1030 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1031 "R[n] = UR[n] >> 16;",
1034 { "", "", "sleep", "0000000000011011",
1035 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
1039 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
1042 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
1043 "R[n] = GET_SR ();",
1045 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
1048 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
1051 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
1055 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1058 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1062 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
1063 "R[n] = Rn_BANK (0);",
1065 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
1066 "R[n] = Rn_BANK (1);",
1068 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
1069 "R[n] = Rn_BANK (2);",
1071 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
1072 "R[n] = Rn_BANK (3);",
1074 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
1075 "R[n] = Rn_BANK (4);",
1077 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
1078 "R[n] = Rn_BANK (5);",
1080 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
1081 "R[n] = Rn_BANK (6);",
1083 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
1084 "R[n] = Rn_BANK (7);",
1086 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
1089 "WLAT (R[n], GBR);;",
1091 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
1094 "WLAT (R[n], GET_SR());",
1096 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
1099 "WLAT (R[n], VBR);",
1101 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
1104 "WLAT (R[n], SSR);",
1106 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
1109 "WLAT (R[n], SPC);",
1112 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1115 "WLAT (R[n], SGR);",
1117 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1120 "WLAT (R[n], DBR);",
1123 { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
1126 "WLAT (R[n], Rn_BANK (0));",
1128 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
1131 "WLAT (R[n], Rn_BANK (1));",
1133 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
1136 "WLAT (R[n], Rn_BANK (2));",
1138 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
1141 "WLAT (R[n], Rn_BANK (3));",
1143 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
1146 "WLAT (R[n], Rn_BANK (4));",
1148 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
1151 "WLAT (R[n], Rn_BANK (5));",
1153 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1156 "WLAT (R[n], Rn_BANK (6));",
1158 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1161 "WLAT (R[n], Rn_BANK (7));",
1165 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1169 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1172 "WLAT (R[n], FPUL);",
1175 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1176 "R[n] = GET_FPSCR ();",
1179 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1182 "WLAT (R[n], GET_FPSCR ());",
1185 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1188 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1191 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1194 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1197 "WLAT (R[n], MACH);",
1199 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1202 "WLAT (R[n], MACL);",
1204 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1210 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1214 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1216 "SET_SR_T (ult > R[n]);",
1217 "R[n] = ult - R[m];",
1218 "SET_SR_T (T || (R[n] > ult));",
1221 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1222 "ult = R[n] - R[m];",
1223 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1227 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1228 "R[n] = ((R[m] & 0xffff0000)",
1229 " | ((R[m] << 8) & 0xff00)",
1230 " | ((R[m] >> 8) & 0x00ff));",
1232 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1233 "R[n] = (((R[m] << 16) & 0xffff0000)",
1234 " | ((R[m] >> 16) & 0x00ffff));",
1237 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1239 "ult = RBAT(R[n]);",
1240 "SET_SR_T (ult == 0);",
1241 "WBAT(R[n],ult|0x80);",
1244 { "0", "", "trapa #<imm>", "11000011i8*1....",
1247 "long imm = 0xff & i;",
1250 "if (i<20||i==34||i==0xc3)",
1251 " trap(i,R,memory,maskl,maskw,little_endian);",
1254 " WLAT(R[15],GET_SR());",
1256 " WLAT(R[15],PC+2);",
1257 " PC=RLAT(VBR+(imm<<2))-2;",
1263 " trap (i, R, memory, maskl, maskw, little_endian);",
1265 "else if (i < 20 || i==34 || i==0xc3)",
1266 " trap (i, R, memory, maskl, maskw, little_endian);",
1267 "else if (!SR_BL) {",
1268 " /* FIXME: TRA = (imm << 2); */",
1271 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1272 " /* FIXME: EXPEVT = 0x00000160; */",
1273 " nia = VBR + 0x00000100;",
1278 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1279 "SET_SR_T ((R[n] & R[m]) == 0);",
1281 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1282 "SET_SR_T ((R0 & i) == 0);",
1284 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1286 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1289 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1292 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1295 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1297 "ult = RBAT (GBR+R0);",
1299 "WBAT (GBR + R0, ult);",
1302 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1303 "R[n] = (((R[n] >> 16) & 0xffff)",
1304 " | ((R[m] << 16) & 0xffff0000));",
1308 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1309 "divl(0,R[n],R[m]);",
1311 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1312 "divl(0,R[n],R[m]);",
1318 /* Tables of things to put into enums for sh-opc.h */
1319 static char *nibble_type_list[] =
1354 char *arg_type_list[] =
1388 make_enum_list (name, s)
1393 printf ("typedef enum {\n");
1396 printf ("\t%s,\n", *s);
1400 printf ("} %s;\n", name);
1410 memcpy (bufa, a->code, 4);
1411 memcpy (bufa + 4, a->code + 12, 4);
1414 memcpy (bufb, b->code, 4);
1415 memcpy (bufb + 4, b->code + 12, 4);
1417 return (strcmp (bufa, bufb));
1431 qsort (tab, len, sizeof (*p), qfunc);
1435 printonmatch (ptr, a, rep)
1441 if (strncmp (*ptr, a, l) == 0)
1461 while (*n && *n != ' ')
1476 while (*p == ',' || *p == ' ')
1478 printonmatch (&p, "#<imm>", "A_IMM");
1479 printonmatch (&p, "R0", "A_R0");
1480 printonmatch (&p, "<REG_N>", "A_REG_N");
1481 printonmatch (&p, "@<REG_N>+", "A_INC_N");
1482 printonmatch (&p, "@<REG_N>", "A_IND_N");
1483 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
1484 printonmatch (&p, "<REG_M>", " A_REG_M");
1485 printonmatch (&p, "@<REG_M>+", "A_INC_M");
1486 printonmatch (&p, "@<REG_M>", "A_IND_M");
1487 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
1488 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
1489 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1490 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1491 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1492 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1493 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
1494 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
1495 printonmatch (&p, "<bdisp8>", "A_BDISP8");
1496 printonmatch (&p, "<bdisp12>", "A_BDISP12");
1497 printonmatch (&p, "SR", "A_SR");
1498 printonmatch (&p, "GBR", "A_GBR");
1499 printonmatch (&p, "VBR", "A_VBR");
1500 printonmatch (&p, "SSR", "A_SSR");
1501 printonmatch (&p, "SPC", "A_SPC");
1502 printonmatch (&p, "MACH", "A_MACH");
1503 printonmatch (&p, "MACL", "A_MACL");
1504 printonmatch (&p, "PR", "A_PR");
1512 printonmatch (&p, "0000", "HEX_0");
1513 printonmatch (&p, "0001", "HEX_1");
1514 printonmatch (&p, "0010", "HEX_2");
1515 printonmatch (&p, "0011", "HEX_3");
1516 printonmatch (&p, "0100", "HEX_4");
1517 printonmatch (&p, "0101", "HEX_5");
1518 printonmatch (&p, "0110", "HEX_6");
1519 printonmatch (&p, "0111", "HEX_7");
1521 printonmatch (&p, "1000", "HEX_8");
1522 printonmatch (&p, "1001", "HEX_9");
1523 printonmatch (&p, "1010", "HEX_A");
1524 printonmatch (&p, "1011", "HEX_B");
1525 printonmatch (&p, "1100", "HEX_C");
1526 printonmatch (&p, "1101", "HEX_D");
1527 printonmatch (&p, "1110", "HEX_E");
1528 printonmatch (&p, "1111", "HEX_F");
1529 printonmatch (&p, "i8*1....", "IMM_8");
1530 printonmatch (&p, "i4*1", "IMM_4");
1531 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
1532 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
1533 printonmatch (&p, "i8*2....", "IMM_8BY2");
1534 printonmatch (&p, "i4*2", "IMM_4BY2");
1535 printonmatch (&p, "i8*4....", "IMM_8BY4");
1536 printonmatch (&p, "i4*4", "IMM_4BY4");
1537 printonmatch (&p, "i12.........", "BRANCH_12");
1538 printonmatch (&p, "i8p1....", "BRANCH_8");
1539 printonmatch (&p, "nnnn", "REG_N");
1540 printonmatch (&p, "mmmm", "REG_M");
1551 for (p = tab; p->name; p++)
1553 printf ("%s %-30s\n", p->code, p->name);
1564 make_enum_list ("sh_nibble_type", nibble_type_list);
1565 make_enum_list ("sh_arg_type", arg_type_list);
1567 printf ("typedef struct {\n");
1568 printf ("char *name;\n");
1569 printf ("sh_arg_type arg[3];\n");
1570 printf ("sh_nibble_type nibbles[4];\n");
1571 printf ("} sh_opcode_info;\n");
1572 printf ("#ifdef DEFINE_TABLE\n");
1573 printf ("sh_opcode_info sh_table[]={\n");
1574 for (p = tab; p->name; p++)
1576 printf ("\n/* %s %-20s*/", p->code, p->name);
1580 printf ("#endif\n");
1588 /* Convert a string of 4 binary digits into an int */
1608 static unsigned char table[1 << 16];
1610 /* Take an opcode expand all varying fields in it out and fill all the
1611 right entries in 'table' with the opcode index*/
1614 expand_opcode (shift, val, i, s)
1638 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1644 for (j = 0; j < 16; j++)
1646 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1652 for (j = 0; j < (1 << (shift + 4)); j++)
1660 /* Print the jump table used to index an opcode into a switch
1675 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1682 printf ("%2d", table[i + j + k]);
1705 for (p = tab; p->name; p++)
1708 expand_opcode (12, 0, p->index, p->code);
1719 printf (" switch (jump_table[iword]) {\n");
1721 for (p = tab; p->name; p++)
1729 printf (" /* %s %s */\n", p->name, p->code);
1730 printf (" case %d: \n", p->index);
1743 printf (" int n = (iword >>8) & 0xf;\n");
1748 printf (" int m = (iword >>4) & 0xf;\n");
1755 printf (" int i = (iword & 0x");
1790 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1791 sextbit - 1, sextbit - 1);
1795 printf (" TB(m,n);\n");
1797 printf (" TL(m);\n");
1799 printf (" TL(n);\n");
1804 for (r = p->refs; *r; r++)
1806 if (*r == '0') printf(" CREF(0);\n");
1807 if (*r == 'n') printf(" CREF(n);\n");
1808 if (*r == 'm') printf(" CREF(m);\n");
1813 for (j = 0; j < MAX_NR_STUFF; j++)
1817 printf (" %s\n", p->stuff[j]);
1825 for (r = p->defs; *r; r++)
1827 if (*r == '0') printf(" CDEF(0);\n");
1828 if (*r == 'n') printf(" CDEF(n);\n");
1829 if (*r == 'm') printf(" CDEF(m);\n");
1833 printf (" break;\n");
1836 printf (" default:\n");
1838 printf (" saved_state.asregs.exception = SIGILL;\n");
1850 for (p = tab; p->name; p++)
1853 printf ("#define OPC_");
1857 if (isalpha(*s)) printf("%c", *s);
1858 if (*s == ' ') printf("_");
1859 if (*s == '@') printf("ind_");
1860 if (*s == ',') printf("_");
1863 printf(" %d\n",p->index);
1872 /* verify the table before anything else */
1875 for (p = tab; p->name; p++)
1877 /* check that the code field contains 16 bits */
1878 if (strlen (p->code) != 16)
1880 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1881 p->code, strlen (p->code), p->name);
1887 /* now generate the requested data */
1890 if (strcmp (av[1], "-t") == 0)
1894 else if (strcmp (av[1], "-d") == 0)
1898 else if (strcmp (av[1], "-s") == 0)
1904 else if (strcmp (av[1], "-x") == 0)