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 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
250 "/* FIXME: check for DP and (n & 1) == 0? */",
254 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
255 "SET_FR (n, (float)0.0);",
256 "/* FIXME: check for DP and (n & 1) == 0? */",
260 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
261 "SET_FR (n, (float)1.0);",
262 "/* FIXME: check for DP and (n & 1) == 0? */",
266 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
268 "*(float *)buf = FR(n);",
269 "FPUL = *(int *)buf;",
273 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
275 " SET_FR (n, (float)FPUL);",
280 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
281 "SET_FR (n, FR(m) * FR(0) + FR(n));",
282 "/* FIXME: check for DP and (n & 1) == 0? */",
286 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
288 " SET_FR (n, FR (m));",
292 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
295 " WLAT (R[n], FI(m));",
299 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
302 " SET_FI(n, RLAT(R[m]));",
306 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
309 " SET_FI (n, RLAT (R[m]));",
314 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
318 " WLAT (R[n], FI(m));",
322 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
325 " SET_FI(n, RLAT(R[0] + R[m]));",
329 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
332 " WLAT((R[0]+R[n]), FI(m));",
337 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
342 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
347 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
348 "FP_UNARY(n, sqrt);",
352 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
357 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
358 "if (FR(n) != FR(n)) /* NaN */",
359 " FPUL = 0x80000000;",
361 " FPUL = (int)FR(n);",
365 { "", "", "ftst/nan <FREG_N>", "1111nnnn01111101",
366 "SET_SR_T (isnan (FR(n)));",
369 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
371 "*(int *)buf = FPUL;",
372 "SET_FR (n, *(float *)buf);",
375 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
377 "Delay_Slot (PC + 2);",
380 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
384 " gotcall (PR, nia);",
385 "Delay_Slot (PC + 2);",
388 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
390 "/* FIXME: user mode */",
392 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
394 "/* FIXME: user mode */",
396 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
398 "/* FIXME: user mode */",
400 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
402 "/* FIXME: user mode */",
404 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
406 "/* FIXME: user mode */",
408 { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
409 "SET_Rn_BANK (0, R[n]);",
410 "/* FIXME: user mode */",
412 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
413 "SET_Rn_BANK (1, R[n]);",
414 "/* FIXME: user mode */",
416 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
417 "SET_Rn_BANK (2, R[n]);",
418 "/* FIXME: user mode */",
420 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
421 "SET_Rn_BANK (3, R[n]);",
422 "/* FIXME: user mode */",
424 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
425 "SET_Rn_BANK (4, R[n]);",
426 "/* FIXME: user mode */",
428 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
429 "SET_Rn_BANK (5, R[n]);",
430 "/* FIXME: user mode */",
432 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
433 "SET_Rn_BANK (6, R[n]);",
434 "/* FIXME: user mode */",
436 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
437 "SET_Rn_BANK (7, R[n]);",
438 "/* FIXME: user mode */",
440 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
442 "GBR = RLAT (R[n]);",
444 "/* FIXME: user mode */",
446 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
448 "SET_SR (RLAT (R[n]));",
450 "/* FIXME: user mode */",
452 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
454 "VBR = RLAT (R[n]);",
456 "/* FIXME: user mode */",
458 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
460 "SSR = RLAT (R[n]);",
462 "/* FIXME: user mode */",
464 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
466 "SPC = RLAT (R[n]);",
468 "/* FIXME: user mode */",
470 { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
472 "SET_Rn_BANK (0, RLAT (R[n]));",
474 "/* FIXME: user mode */",
476 { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
478 "SET_Rn_BANK (1, RLAT (R[n]));",
480 "/* FIXME: user mode */",
482 { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
484 "SET_Rn_BANK (2, RLAT (R[n]));",
486 "/* FIXME: user mode */",
488 { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
490 "SET_Rn_BANK (3, RLAT (R[n]));",
492 "/* FIXME: user mode */",
494 { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
496 "SET_Rn_BANK (4, RLAT (R[n]));",
498 "/* FIXME: user mode */",
500 { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
502 "SET_Rn_BANK (5, RLAT (R[n]));",
504 "/* FIXME: user mode */",
506 { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
508 "SET_Rn_BANK (6, RLAT (R[n]));",
510 "/* FIXME: user mode */",
512 { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
514 "SET_Rn_BANK (7, RLAT (R[n]));",
516 "/* FIXME: user mode */",
520 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
524 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
526 "FPUL = RLAT(R[n]);",
530 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
534 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
536 "SET_FPSCR (RLAT(R[n]));",
540 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
543 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
546 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
549 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
551 "MACH = SEXT(RLAT(R[n]));",
554 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
556 "MACL = RLAT(R[n]);",
559 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
565 { "", "", "ldtlb", "0000000000111000",
566 "/* FIXME: XXX*/ abort();",
569 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
570 "trap (255,R0,memory,maskl,maskw,little_endian);",
571 "/* FIXME: mac.l support */",
574 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
575 "macw(R0,memory,n,m);",
578 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
581 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
585 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
587 "R0 = RSBAT (i + GBR);",
590 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
592 "R0 = RSBAT (i + R[m]);",
595 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
597 "R[n] = RSBAT (R0 + R[m]);",
600 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
602 "R[n] = RSBAT (R[m]);",
606 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
608 "WBAT (R[n], R[m]);",
610 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
612 "WBAT (i + GBR, R0);",
614 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
616 "WBAT (i + R[m], R0);",
618 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
620 "WBAT (R[n] + R0, R[m]);",
622 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
625 "WBAT (R[n], R[m]);",
627 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
629 "R[n] = RSBAT (R[m]);",
633 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
635 "R0 = RLAT (i + GBR);",
638 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
640 "R[n] = RLAT((PC & ~3) + 4 + i);",
643 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
645 "R[n] = RLAT (i + R[m]);",
648 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
650 "R[n] = RLAT (R0 + R[m]);",
653 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
655 "R[n] = RLAT (R[m]);",
659 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
661 "R[n] = RLAT (R[m]);",
664 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
666 "WLAT (i + GBR, R0);",
668 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
670 "WLAT (i + R[n], R[m]);",
672 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
674 "WLAT (R0 + R[n], R[m]);",
676 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
679 "WLAT (R[n], R[m]);",
681 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
683 "WLAT (R[n], R[m]);",
686 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
688 ";R0 = RSWAT (i + GBR);",
691 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
693 "R[n] = RSWAT (PC + 4 + i);",
696 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
698 "R0 = RSWAT (i + R[m]);",
701 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
703 "R[n] = RSWAT (R0 + R[m]);",
706 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
708 "R[n] = RSWAT (R[m]);",
712 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
714 "R[n] = RSWAT (R[m]);",
717 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
719 "WWAT (i + GBR, R0);",
721 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
723 "WWAT (i + R[m], R0);",
725 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
727 "WWAT (R0 + R[n], R[m]);",
729 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
732 "WWAT (R[n], R[m]);",
734 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
736 "WWAT (R[n], R[m]);",
739 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
740 "R0 = ((i + 4 + PC) & ~0x3);",
743 { "n", "", "movt <REG_N>", "0000nnnn00101001",
747 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
748 "MACL = ((int)R[n]) * ((int)R[m]);",
751 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
752 "MACL = R[n] * R[m];",
756 /* muls.w - see muls */
757 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
758 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
761 /* mulu.w - see mulu */
762 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
763 "MACL = (((unsigned int)(unsigned short)R[n])",
764 " * ((unsigned int)(unsigned short)R[m]));",
767 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
771 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
773 "SET_SR_T (ult > 0);",
774 "R[n] = ult - R[m];",
775 "SET_SR_T (T || (R[n] > ult));",
778 { "", "", "nop", "0000000000001001",
782 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
786 { "0", "", "or #<imm>,R0", "11001011i8*1....",
789 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
792 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
794 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
797 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
798 "/* Except for the effect on the cache - which is not simulated -",
799 " this is like a nop. */",
802 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
804 "R[n] = (R[n] << 1) | T;",
808 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
810 "R[n] = (UR[n] >> 1) | (T << 31);",
814 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
815 "SET_SR_T (R[n] < 0);",
820 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
821 "SET_SR_T (R[n] & 1);",
822 "R[n] = UR[n] >> 1;",
823 "R[n] |= (T << 31);",
826 { "", "", "rte", "0000000000101011",
830 "nia = RLAT (R[15]) + 2;",
832 "SET_SR (RLAT (R[15]) & 0x3f3);",
834 "Delay_Slot (PC + 2);",
838 "Delay_Slot (PC + 2);",
842 { "", "", "rts", "0000000000001011",
844 "Delay_Slot (PC + 2);",
847 { "", "", "sets", "0000000001011000",
851 { "", "", "sett", "0000000000011000",
855 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
856 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
859 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
860 "SET_SR_T (R[n] < 0);",
864 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
865 "SET_SR_T (R[n] & 1);",
869 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
870 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
873 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
874 "SET_SR_T (R[n] < 0);",
878 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
881 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
884 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
888 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
889 "SET_SR_T (R[n] & 1);",
890 "R[n] = UR[n] >> 1;",
893 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
894 "R[n] = UR[n] >> 2;",
896 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
897 "R[n] = UR[n] >> 8;",
899 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
900 "R[n] = UR[n] >> 16;",
903 { "", "", "sleep", "0000000000011011",
904 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
908 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
911 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
914 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
917 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
920 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
923 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
924 "R[n] = Rn_BANK (0);",
926 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
927 "R[n] = Rn_BANK (1);",
929 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
930 "R[n] = Rn_BANK (2);",
932 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
933 "R[n] = Rn_BANK (3);",
935 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
936 "R[n] = Rn_BANK (4);",
938 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
939 "R[n] = Rn_BANK (5);",
941 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
942 "R[n] = Rn_BANK (6);",
944 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
945 "R[n] = Rn_BANK (7);",
947 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
950 "WLAT (R[n], GBR);;",
952 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
955 "WLAT (R[n], GET_SR());",
957 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
962 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
967 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
972 { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
975 "WLAT (R[n], Rn_BANK (0));",
977 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
980 "WLAT (R[n], Rn_BANK (1));",
982 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
985 "WLAT (R[n], Rn_BANK (2));",
987 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
990 "WLAT (R[n], Rn_BANK (3));",
992 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
995 "WLAT (R[n], Rn_BANK (4));",
997 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
1000 "WLAT (R[n], Rn_BANK (5));",
1002 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1005 "WLAT (R[n], Rn_BANK (6));",
1007 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1010 "WLAT (R[n], Rn_BANK (7));",
1014 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1018 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1021 "WLAT (R[n], FPUL);",
1024 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1025 "R[n] = GET_FPSCR ();",
1028 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1031 "WLAT (R[n], GET_FPSCR ());",
1034 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1037 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1040 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1043 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1046 "WLAT (R[n], MACH);",
1048 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1051 "WLAT (R[n], MACL);",
1053 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1059 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1063 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1065 "SET_SR_T (ult > R[n]);",
1066 "R[n] = ult - R[m];",
1067 "SET_SR_T (T || (R[n] > ult));",
1070 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1071 "ult = R[n] - R[m];",
1072 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1076 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1077 "R[n] = ((R[m] & 0xffff0000)",
1078 " | ((R[m] << 8) & 0xff00)",
1079 " | ((R[m] >> 8) & 0x00ff));",
1081 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1082 "R[n] = (((R[m] << 16) & 0xffff0000)",
1083 " | ((R[m] >> 16) & 0x00ffff));",
1086 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1088 "ult = RBAT(R[n]);",
1089 "SET_SR_T (ult == 0);",
1090 "WBAT(R[n],ult|0x80);",
1093 { "0", "", "trapa #<imm>", "11000011i8*1....",
1096 "long imm = 0xff & i;",
1099 "if (i<20||i==34||i==0xc3)",
1100 " trap(i,R,memory,maskl,maskw,little_endian);",
1103 " WLAT(R[15],GET_SR());",
1105 " WLAT(R[15],PC+2);",
1106 " PC=RLAT(VBR+(imm<<2))-2;",
1112 " trap (i, R, memory, maskl, maskw, little_endian);",
1114 "else if (i < 20 || i==34 || i==0xc3)",
1115 " trap (i, R, memory, maskl, maskw, little_endian);",
1116 "else if (!SR_BL) {",
1117 " /* FIXME: TRA = (imm << 2); */",
1120 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1121 " /* FIXME: EXPEVT = 0x00000160; */",
1122 " nia = VBR + 0x00000100;",
1127 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1128 "SET_SR_T ((R[n] & R[m]) == 0);",
1130 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1131 "SET_SR_T ((R0 & i) == 0);",
1133 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1135 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1138 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1141 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1144 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1146 "ult = RBAT (GBR+R0);",
1148 "WBAT (GBR + R0, ult);",
1151 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1152 "R[n] = (((R[n] >> 16) & 0xffff)",
1153 " | ((R[m] << 16) & 0xffff0000));",
1158 /* Tables of things to put into enums for sh-opc.h */
1159 static char *nibble_type_list[] =
1194 char *arg_type_list[] =
1228 make_enum_list (name, s)
1233 printf ("typedef enum {\n");
1236 printf ("\t%s,\n", *s);
1240 printf ("} %s;\n", name);
1250 memcpy (bufa, a->code, 4);
1251 memcpy (bufa + 4, a->code + 12, 4);
1254 memcpy (bufb, b->code, 4);
1255 memcpy (bufb + 4, b->code + 12, 4);
1257 return (strcmp (bufa, bufb));
1271 qsort (tab, len, sizeof (*p), qfunc);
1275 printonmatch (ptr, a, rep)
1281 if (strncmp (*ptr, a, l) == 0)
1301 while (*n && *n != ' ')
1316 while (*p == ',' || *p == ' ')
1318 printonmatch (&p, "#<imm>", "A_IMM");
1319 printonmatch (&p, "R0", "A_R0");
1320 printonmatch (&p, "<REG_N>", "A_REG_N");
1321 printonmatch (&p, "@<REG_N>+", "A_INC_N");
1322 printonmatch (&p, "@<REG_N>", "A_IND_N");
1323 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
1324 printonmatch (&p, "<REG_M>", " A_REG_M");
1325 printonmatch (&p, "@<REG_M>+", "A_INC_M");
1326 printonmatch (&p, "@<REG_M>", "A_IND_M");
1327 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
1328 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
1329 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1330 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1331 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1332 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1333 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
1334 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
1335 printonmatch (&p, "<bdisp8>", "A_BDISP8");
1336 printonmatch (&p, "<bdisp12>", "A_BDISP12");
1337 printonmatch (&p, "SR", "A_SR");
1338 printonmatch (&p, "GBR", "A_GBR");
1339 printonmatch (&p, "VBR", "A_VBR");
1340 printonmatch (&p, "SSR", "A_SSR");
1341 printonmatch (&p, "SPC", "A_SPC");
1342 printonmatch (&p, "MACH", "A_MACH");
1343 printonmatch (&p, "MACL", "A_MACL");
1344 printonmatch (&p, "PR", "A_PR");
1352 printonmatch (&p, "0000", "HEX_0");
1353 printonmatch (&p, "0001", "HEX_1");
1354 printonmatch (&p, "0010", "HEX_2");
1355 printonmatch (&p, "0011", "HEX_3");
1356 printonmatch (&p, "0100", "HEX_4");
1357 printonmatch (&p, "0101", "HEX_5");
1358 printonmatch (&p, "0110", "HEX_6");
1359 printonmatch (&p, "0111", "HEX_7");
1361 printonmatch (&p, "1000", "HEX_8");
1362 printonmatch (&p, "1001", "HEX_9");
1363 printonmatch (&p, "1010", "HEX_A");
1364 printonmatch (&p, "1011", "HEX_B");
1365 printonmatch (&p, "1100", "HEX_C");
1366 printonmatch (&p, "1101", "HEX_D");
1367 printonmatch (&p, "1110", "HEX_E");
1368 printonmatch (&p, "1111", "HEX_F");
1369 printonmatch (&p, "i8*1....", "IMM_8");
1370 printonmatch (&p, "i4*1", "IMM_4");
1371 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
1372 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
1373 printonmatch (&p, "i8*2....", "IMM_8BY2");
1374 printonmatch (&p, "i4*2", "IMM_4BY2");
1375 printonmatch (&p, "i8*4....", "IMM_8BY4");
1376 printonmatch (&p, "i4*4", "IMM_4BY4");
1377 printonmatch (&p, "i12.........", "BRANCH_12");
1378 printonmatch (&p, "i8p1....", "BRANCH_8");
1379 printonmatch (&p, "nnnn", "REG_N");
1380 printonmatch (&p, "mmmm", "REG_M");
1391 for (p = tab; p->name; p++)
1393 printf ("%s %-30s\n", p->code, p->name);
1404 make_enum_list ("sh_nibble_type", nibble_type_list);
1405 make_enum_list ("sh_arg_type", arg_type_list);
1407 printf ("typedef struct {\n");
1408 printf ("char *name;\n");
1409 printf ("sh_arg_type arg[3];\n");
1410 printf ("sh_nibble_type nibbles[4];\n");
1411 printf ("} sh_opcode_info;\n");
1412 printf ("#ifdef DEFINE_TABLE\n");
1413 printf ("sh_opcode_info sh_table[]={\n");
1414 for (p = tab; p->name; p++)
1416 printf ("\n/* %s %-20s*/", p->code, p->name);
1420 printf ("#endif\n");
1428 /* Convert a string of 4 binary digits into an int */
1448 static unsigned char table[1 << 16];
1450 /* Take an opcode expand all varying fields in it out and fill all the
1451 right entries in 'table' with the opcode index*/
1454 expand_opcode (shift, val, i, s)
1478 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1484 for (j = 0; j < 16; j++)
1486 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1492 for (j = 0; j < (1 << (shift + 4)); j++)
1500 /* Print the jump table used to index an opcode into a switch
1515 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1522 printf ("%2d", table[i + j + k]);
1545 for (p = tab; p->name; p++)
1548 expand_opcode (12, 0, p->index, p->code);
1559 printf (" switch (jump_table[iword]) {\n");
1561 for (p = tab; p->name; p++)
1569 printf (" /* %s %s */\n", p->name, p->code);
1570 printf (" case %d: \n", p->index);
1583 printf (" int n = (iword >>8) & 0xf;\n");
1588 printf (" int m = (iword >>4) & 0xf;\n");
1595 printf (" int i = (iword & 0x");
1630 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1631 sextbit - 1, sextbit - 1);
1635 printf (" TB(m,n);\n");
1637 printf (" TL(m);\n");
1639 printf (" TL(n);\n");
1644 for (r = p->refs; *r; r++)
1646 if (*r == '0') printf(" CREF(0);\n");
1647 if (*r == 'n') printf(" CREF(n);\n");
1648 if (*r == 'm') printf(" CREF(m);\n");
1653 for (j = 0; j < MAX_NR_STUFF; j++)
1657 printf (" %s\n", p->stuff[j]);
1665 for (r = p->defs; *r; r++)
1667 if (*r == '0') printf(" CDEF(0);\n");
1668 if (*r == 'n') printf(" CDEF(n);\n");
1669 if (*r == 'm') printf(" CDEF(m);\n");
1673 printf (" break;\n");
1676 printf (" default:\n");
1678 printf (" saved_state.asregs.exception = SIGILL;\n");
1690 for (p = tab; p->name; p++)
1693 printf ("#define OPC_");
1697 if (isalpha(*s)) printf("%c", *s);
1698 if (*s == ' ') printf("_");
1699 if (*s == '@') printf("ind_");
1700 if (*s == ',') printf("_");
1703 printf(" %d\n",p->index);
1712 /* verify the table before anything else */
1715 for (p = tab; p->name; p++)
1717 /* check that the code field contains 16 bits */
1718 if (strlen (p->code) != 16)
1720 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1721 p->code, strlen (p->code), p->name);
1727 /* now generate the requested data */
1730 if (strcmp (av[1], "-t") == 0)
1734 else if (strcmp (av[1], "-d") == 0)
1738 else if (strcmp (av[1], "-s") == 0)
1744 else if (strcmp (av[1], "-x") == 0)