* gencode.c (tab): Added several sh3 opcodes.
[external/binutils.git] / sim / sh / gencode.c
1 /* Simulator/Opcode generator for the Hitachi Super-H architecture.
2
3    Written by Steve Chamberlain of Cygnus Support.
4    sac@cygnus.com
5
6    This file is part of SH sim
7
8
9                 THIS SOFTWARE IS NOT COPYRIGHTED
10
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.
14
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.
18
19 */
20
21 /* This program generates the opcode table for the assembler and
22    the simulator code
23
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
29
30 */
31
32 #include <stdio.h>
33
34 typedef struct
35 {
36 char *defs;
37 char *refs;
38   char *name;
39   char *code;
40   char *stuff[10];
41   int index;
42 }
43
44 op;
45
46
47 op tab[] =
48 {
49
50   {"n","","add #<imm>,<REG_N>", "0111nnnni8*1....", "R[n] += SEXT(i);if (i == 0) { UNDEF(n); break; } "},
51   {"n","mn","add <REG_M>,<REG_N>", "0011nnnnmmmm1100", "R[n] += R[m];"},
52   {"n","mn","addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
53      "ult=R[n]+T;T=ult<R[n];R[n]=ult+R[m];T|=R[n]<ult;"},
54   {"n","mn","addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
55      "ult = R[n] + R[m]; T = ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31); R[n] = ult;"},
56   {"0","","and #<imm>,R0", "11001001i8*1....", ";R0&=i;"},
57   {"n","nm","and <REG_M>,<REG_N>", "0010nnnnmmmm1001", " R[n]&=R[m];"},
58   {"","0","and.b #<imm>,@(R0,GBR)", "11001101i8*1....", ";WBAT(GBR+R0, RBAT(GBR+R0) & i);"},
59
60   {"","","bra <bdisp12>", "1010i12.........", "ult = PC; PC=PC+(i<<1)+2;SL(ult+2);"},
61   {"","","bsr <bdisp12>", "1011i12.........", "PR = PC + 4; PC=PC+(i<<1)+2;SL(PR-2);"},
62   {"","","bt <bdisp8>", "10001001i8p1....", "if(T) {PC+=(SEXT(i)<<1)+2;C+=2;}"},
63   {"","","bf <bdisp8>", "10001011i8p1....", "if(T==0) {PC+=(SEXT(i)<<1)+2;C+=2;}"},
64   {"","","bt.s <bdisp8>", "10001101i8p1....","if(T) {ult = PC; PC+=(SEXT(i)<<1)+2;C+=2;SL(ult+2);}"},
65   {"","","bf.s <bdisp8>", "10001111i8p1....","if(!T) {ult = PC; PC+=(SEXT(i)<<1)+2;C+=2;SL(ult+2);}"},
66   {"","","clrmac", "0000000000101000", "MACH = MACL = 0;"},
67   {"","","clrs", "0000000001001000", "S= 0;"},
68   {"","","clrt", "0000000000001000", "T= 0;"},
69   {"","0","cmp/eq #<imm>,R0", "10001000i8*1....", ";T = R0 == SEXT(i);"},
70   {"","mn","cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000", "T=R[n]==R[m];"},
71   {"","mn","cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011", "T=R[n]>=R[m];"},
72   {"","mn","cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111", "T=R[n]>R[m];"},
73   {"","mn","cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110", "T=UR[n]>UR[m];"},
74   {"","mn","cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010", "T=UR[n]>=UR[m];"},
75   {"","n","cmp/pl <REG_N>", "0100nnnn00010101", "T = R[n]>0;"},
76   {"","n","cmp/pz <REG_N>", "0100nnnn00010001", "T = R[n]>=0;"},
77   {"","mn","cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
78    "ult = R[n] ^ R[m]; T=((ult&0xff000000)==0) |((ult&0xff0000)==0) |((ult&0xff00)==0) |((ult&0xff)==0); "},
79   {"","mn","div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111", "Q=(R[n]&sbit)!=0; M=(R[m]&sbit)!=0; T=M!=Q;;"},
80   {"","","div0u", "0000000000011001", "M=Q=T=0;"},
81   {"","","div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", "T=div1(R,m,n,T);"},
82   {"n","m","exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110", "R[n] = SEXT(R[m]);"},
83   {"n","m","exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111", "R[n] = SEXTW(R[m]);"},
84   {"n","m","extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100", "R[n] = R[m] & 0xff;"},
85   {"n","m","extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101", "R[n] = R[m] & 0xffff;"},
86   {"","n","jmp @<REG_N>", "0100nnnn00101011", "ult = PC; PC=R[n]-2; SL(ult+2);"},
87   {"","n","jsr @<REG_N>", "0100nnnn00001011", "PR = PC + 4; PC=R[n]-2; if (~doprofile) gotcall(PR,PC+2);SL(PR-2);"},
88   {"","n","ldc <REG_N>,SR", "0100nnnn00001110", "SET_SR(R[n]);"},
89   {"","n","ldc <REG_N>,GBR", "0100nnnn00011110", "GBR=R[n];"},
90   {"","n","ldc <REG_N>,VBR", "0100nnnn00101110", "VBR=R[n];"},
91   {"","n","ldc <REG_N>,SSR", "0100nnnn00111110", "SSR=R[n];"},
92   {"","n","ldc <REG_N>,SPC", "0100nnnn01001110", "SPC=R[n];"},
93   {"","n","ldc.l @<REG_N>+,SR", "0100nnnn00000111", "SET_SR(RLAT(R[n]));R[n]+=4;;"},
94   {"","n","ldc.l @<REG_N>+,GBR", "0100nnnn00010111", "GBR=RLAT(R[n]);R[n]+=4;;"},
95   {"","n","ldc.l @<REG_N>+,VBR", "0100nnnn00100111", "VBR=RLAT(R[n]);R[n]+=4;;"},
96   {"","n","ldc.l @<REG_N>+,SSR", "0100nnnn00110111", "SSR=RLAT(R[n]);R[n]+=4;;"},
97   {"","n","ldc.l @<REG_N>+,SPC", "0100nnnn01000111", "SPC=RLAT(R[n]);R[n]+=4;;"},
98   {"","n","lds <REG_N>,MACH", "0100nnnn00001010", "MACH = R[n];"},
99   {"","n","lds <REG_N>,MACL", "0100nnnn00011010", "MACL= R[n];"},
100   {"","n","lds <REG_N>,PR", "0100nnnn00101010", "PR = R[n];"},
101   {"","n","lds.l @<REG_N>+,MACH", "0100nnnn00000110", "MACH = SEXT(RLAT(R[n]));R[n]+=4;"},
102   {"","n","lds.l @<REG_N>+,MACL", "0100nnnn00010110", "MACL = RLAT(R[n]);R[n]+=4;"},
103   {"","n","lds.l @<REG_N>+,PR", "0100nnnn00100110", "PR = RLAT(R[n]);R[n]+=4;;"},
104   {"","","ldtlb", "0000000000111000", "/*XXX*/ abort();"},
105   {"","n","mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111", "macw(R0,memory,n,m);"},
106   {"n","","mov #<imm>,<REG_N>", "1110nnnni8*1....", "R[n] = SEXT(i);"},
107   {"n","m","mov <REG_M>,<REG_N>", "0110nnnnmmmm0011", "R[n] = R[m];"},
108   {"","mn0","mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100", "WBAT(R[n]+R0, R[m]);"},
109   {"","nm","mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100", "R[n]--; WBAT(R[n],R[m]);"},
110   {"","mn","mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000", "WBAT(R[n], R[m]);"},
111   {"0","m","mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1", "R0=RSBAT(i+R[m]);L(0);"},
112   {"0","","mov.b @(<disp>,GBR),R0", "11000100i8*1....", "R0=RSBAT(i+GBR);L(0);"},
113   {"n","0m","mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100", "R[n]=RSBAT(R0+R[m]);L(n);"},
114   {"n","m","mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100", "R[n] = RSBAT(R[m]);L(n);R[m]++;"},
115   {"n","m","mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000", "R[n]=RSBAT(R[m]);L(n);"},
116   {"","m0","mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1", "WBAT(i+R[m],R0);"},
117   {"","0","mov.b R0,@(<disp>,GBR)", "11000000i8*1....", "WBAT(i+GBR,R0);"},
118   {"","nm","mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",   "WLAT(i+R[n],R[m]);"},
119   {"","nm0","mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110", "WLAT(R0+R[n],R[m]);"},
120   {"","nm","mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110", "R[n]-=4;WLAT(R[n],R[m]);"},
121   {"","nm","mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010", "WLAT(R[n], R[m]);"},
122   {"n","m","mov.l @(<disp>,<REG_M>),<REG_N>","0101nnnnmmmmi4*4", "R[n]=RLAT(i+R[m]);L(n);"},
123   {"0","","mov.l @(<disp>,GBR),R0", "11000110i8*4....", "R0=RLAT(i+GBR);L(0);"},
124   {"n","","mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....", "R[n]=RLAT((i+4+PC) & ~3);L(n);"},
125   {"n","m","mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110", "R[n]=RLAT(R0+R[m]);L(n);"},
126 {"nm","m","mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110", "R[n]=RLAT(R[m]);R[m]+=4;L(n);"},
127   {"n","m","mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010", "R[n]=RLAT(R[m]);L(n);"},
128   {"","0","mov.l R0,@(<disp>,GBR)", "11000010i8*4....", "WLAT(i+GBR,R0);"},
129   {"","m0n","mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101", "WWAT(R0+R[n],R[m]);"},
130 {"n","mn","mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101", "R[n]-=2;WWAT(R[n],R[m]);"},
131   {"","nm","mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001", "WWAT(R[n],R[m]);"},
132   {"0","m","mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2", "R0=RSWAT(i+R[m]);L(0);"},
133   {"0","","mov.w @(<disp>,GBR),R0", "11000101i8*2....", "R0=RSWAT(i+GBR);L(0);"},
134   {"n","","mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....", "R[n]=RSWAT(PC+i+4);L(n);"},
135 {"n","m0","mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101", "R[n]=RSWAT(R0+R[m]);L(n);"},
136 {"nm","n","mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101", "R[n]=RSWAT(R[m]);R[m]+=2;L(n);"},
137   {"n","m","mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001", "R[n]=RSWAT(R[m]);L(n);"},
138   {"","0m","mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",   "WWAT(i+R[m],R0);"},
139   {"","0","mov.w R0,@(<disp>,GBR)", "11000001i8*2....", "WWAT(i+GBR,R0);"},
140   {"0","","mova @(<disp>,PC),R0", "11000111i8p4....", "R0=((i+4+PC) & ~0x3);"},
141   {"n","","movt <REG_N>", "0000nnnn00101001", "R[n]=T;"},
142   {"","mn","muls <REG_M>,<REG_N>", "0010nnnnmmmm1111","MACL=((int)(short)R[n])*((int)(short)R[m]);"},
143   {"","mn","mul.l <REG_M>,<REG_N>","0000nnnnmmmm0111","MACL=((int)R[n])*((int)R[m]);"},
144   {"","mn","mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110","MACL=((unsigned int)(unsigned short)R[n])*((unsigned int)(unsigned short)R[m]);"},
145   {"n","m","neg <REG_M>,<REG_N>", "0110nnnnmmmm1011", "R[n] = - R[m];"},
146   {"n","m","negc <REG_M>,<REG_N>", "0110nnnnmmmm1010", "ult=-T;T=ult>0;R[n]=ult-R[m];T|=R[n]>ult;"},
147   {"","","nop", "0000000000001001", ""},
148   {"n","m","not <REG_M>,<REG_N>", "0110nnnnmmmm0111", "R[n]=~R[m];"},
149   {"0","","or #<imm>,R0", "11001011i8*1....", "R0|=i;"},
150   {"n","m","or <REG_M>,<REG_N>", "0010nnnnmmmm1011", "R[n]|=R[m];"},
151   {"","0","or.b #<imm>,@(R0,GBR)", "11001111i8*1....", "WBAT(R0+GBR,RBAT(R0+GBR)|i);"},
152 {"n","n","rotcl <REG_N>", "0100nnnn00100100", "ult=R[n]<0;R[n]=(R[n]<<1)|T;T=ult;"},
153   {"n","n","rotcr <REG_N>", "0100nnnn00100101", "ult=R[n]&1;R[n]=(UR[n]>>1)|(T<<31);T=ult;"},
154   {"n","n","rotl <REG_N>", "0100nnnn00000100", "T=R[n]<0;R[n]<<=1;R[n]|=T;"},
155   {"n","n","rotr <REG_N>", "0100nnnn00000101", "T=R[n]&1;R[n] = UR[n]>> 1;R[n]|=(T<<31);"},
156   {"","","rte", "0000000000101011", 
157     "{ int tmp = PC; PC=RLAT(R[15])+2;R[15]+=4;SET_SR(RLAT(R[15]) & 0x3f3);R[15]+=4;SL(tmp+2);}"},
158   {"","","rts", "0000000000001011", "ult=PC;PC=PR-2;SL(ult+2);"},
159   {"","","sets", "0000000001011000", "S=1;"},
160   {"","","sett", "0000000000011000", "T=1;"},
161   {"n","mn","shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
162     "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));"},
163   {"n","mn","shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
164     "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));"},
165   {"n","n","shal <REG_N>", "0100nnnn00100000", "T=R[n]<0; R[n]<<=1;"},
166   {"n","n","shar <REG_N>", "0100nnnn00100001", "T=R[n]&1; R[n] = R[n] >> 1;"},
167   {"n","n","shll <REG_N>", "0100nnnn00000000", "T=R[n]<0; R[n]<<=1;"},
168   {"n","n","shll16 <REG_N>", "0100nnnn00101000", "R[n]<<=16;"},
169   {"n","n","shll2 <REG_N>", "0100nnnn00001000", "R[n]<<=2;"},
170   {"n","n","shll8 <REG_N>", "0100nnnn00011000", "R[n]<<=8;"},
171   {"n","n","shlr <REG_N>", "0100nnnn00000001", "T=R[n]&1;R[n]=UR[n]>>1;"},
172   {"n","n","shlr16 <REG_N>", "0100nnnn00101001", "R[n]=UR[n]>>16;"},
173   {"n","n","shlr2 <REG_N>", "0100nnnn00001001", "R[n]=UR[n]>>2;"},
174   {"n","n","shlr8 <REG_N>", "0100nnnn00011001", "R[n]=UR[n]>>8;"},
175   {"","","sleep", "0000000000011011", "trap(0xc3,R0,memory,maskl,maskw,little_endian);PC-=2;"},
176   {"n","","stc SR,<REG_N>",  "0000nnnn00000010", "R[n]=GET_SR();"},
177   {"n","","stc GBR,<REG_N>", "0000nnnn00010010", "R[n]=GBR;"},
178   {"n","","stc VBR,<REG_N>", "0000nnnn00100010", "R[n]=VBR;"},
179   {"n","","stc SSR,<REG_N>", "0000nnnn00110010", "R[n]=SSR;"},
180   {"n","","stc SPC,<REG_N>", "0000nnnn01000010", "R[n]=SPC;"},
181   {"n","n","stc.l SR,@-<REG_N>",  "0100nnnn00000011", "R[n]-=4;WLAT(R[n],GET_SR());"},
182   {"n","n","stc.l GBR,@-<REG_N>", "0100nnnn00010011", "R[n]-=4;WLAT(R[n],GBR);;"},
183   {"n","n","stc.l VBR,@-<REG_N>", "0100nnnn00100011", "R[n]-=4;WLAT(R[n],VBR);"},
184   {"n","n","stc.l SSR,@-<REG_N>", "0100nnnn00110011", "R[n]-=4;WLAT(R[n],SSR);"},
185   {"n","n","stc.l SPC,@-<REG_N>", "0100nnnn01000011", "R[n]-=4;WLAT(R[n],SPC);"},
186   {"n","","sts MACH,<REG_N>", "0000nnnn00001010", "R[n]=MACH;"},
187   {"n","","sts MACL,<REG_N>", "0000nnnn00011010", "R[n]=MACL;"},
188   {"n","","sts PR,<REG_N>", "0000nnnn00101010", "R[n]=PR;"},
189   {"n","n","sts.l MACH,@-<REG_N>", "0100nnnn00000010", "R[n]-=4;WLAT(R[n],MACH);"},
190   {"n","n","sts.l MACL,@-<REG_N>", "0100nnnn00010010", "R[n]-=4;WLAT(R[n],MACL);"},
191   {"n","n","sts.l PR,@-<REG_N>", "0100nnnn00100010", "R[n]-=4;WLAT(R[n],PR);"},
192   {"n","nm","sub <REG_M>,<REG_N>", "0011nnnnmmmm1000", "R[n]-=R[m];"},
193 {"n","nm","subc <REG_M>,<REG_N>", "0011nnnnmmmm1010", "ult=R[n]-T;T=ult>R[n];R[n]=ult-R[m];T|=R[n]>ult;"},
194   {"n","nm","subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
195      "ult = R[n] - R[m]; T = (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31); R[n] = ult;"},
196   {"n","nm","swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000", "R[n]=((R[m]<<8)&0xff00)|((R[m]>>8)&0x00ff);"},
197   {"n","nm","swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001", "R[n]=((R[m]<<16)&0xffff0000)|((R[m]>>16)&0x00ffff);"},
198   {"","n","tas.b @<REG_N>", "0100nnnn00011011", "ult=RBAT(R[n]);T=ult==0;WBAT(R[n],ult|0x80);"},
199   {"0","","trapa #<imm>", "11000011i8*1....", 
200      "{ long imm = 0xff & i; if (i==0xc3) PC-=2; if (i<20||i==34||i==0xc3) trap(i,R,memory,maskl,maskw,little_endian); else { R[15]-=4; WLAT(R[15],GET_SR()); R[15]-=4;WLAT(R[15],PC+2); PC=RLAT(VBR+(imm<<2))-2;}}"},
201   {"","0","tst #<imm>,R0", "11001000i8*1....", "T=(R0&i)==0;"},
202   {"","mn","tst <REG_M>,<REG_N>", "0010nnnnmmmm1000", "T=(R[n]&R[m])==0;"},
203   {"","0","tst.b #<imm>,@(R0,GBR)", "11001100i8*1....", "T=(RBAT(GBR+R0)&i)==0;"},
204   {"","0","xor #<imm>,R0", "11001010i8*1....", "R0^=i;"},
205   {"n","mn","xor <REG_M>,<REG_N>", "0010nnnnmmmm1010", "R[n]^=R[m];"},
206   {"","0","xor.b #<imm>,@(R0,GBR)", "11001110i8*1....", "ult=RBAT(GBR+R0);ult^=i;WBAT(GBR+R0,ult);"},
207   {"n","nm","xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101", "R[n]=((R[n]>>16)&0xffff)|((R[m]<<16)&0xffff0000);"},
208   {"","nm","mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111", " MACL = R[n] * R[m];"},
209   {"n","n","dt <REG_N>", "0100nnnn00010000", "R[n]--; T=R[n] == 0;"},
210   {"","nm","dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101", "dmul(1,R[n],R[m]);"},
211   {"","nm","dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101", "dmul(0,R[n],R[m]);"},
212   {"","nm","mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111", "abort();"},
213   {"","n","braf <REG_N>", "0000nnnn00100011", "ult = PC; PC+=R[n]-2;SL(ult+2);"},
214   {"","n","bsrf <REG_N>", "0000nnnn00000011", "PR = PC + 4; PC+=R[n]-2;SL(PR-2);"},
215 #if 0
216   {"divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110", "divl(0,R[n],R[m]);"},
217   {"divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101", "divl(0,R[n],R[m]);"},
218 #endif
219
220 /* start-sanitize-sh3e */
221   {"", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000", "*(int *)buf = RLAT(R[m]);F[n] = *(float *)buf;"},
222   {"", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010", "*(float *)buf = F[m]; WLAT(R[n], *(int *)buf);"},
223   {"", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001", "*(int *)buf = RLAT(R[m]); F[n] = *(float *)buf; R[m] += 4;"},
224   {"", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011", "R[n] -= 4; *(float *)buf = F[m]; WLAT(R[n], *(int *)buf);"},
225   {"", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110", "*(int *)buf = RLAT((R[0]+R[m]));F[n] = *(float *)buf;"},
226   {"", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111", "*(float *)buf = F[m]; WLAT((R[0]+R[n]), *(int *)buf);"},
227   {"", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100", "F[n] = F[m];"},
228   {"", "", "fldi0 <FREG_N>", "1111nnnn10001101", "F[n] = (float)0.0;"},
229   {"", "", "fldi1 <FREG_N>", "1111nnnn10011101", "F[n] = (float)1.0;"},
230   {"", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000","F[n] = F[n] + F[m];"},
231   {"", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001","F[n] = F[n] - F[m];"},
232   {"", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010","F[n] = F[n] * F[m];"},
233   {"", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011","F[n] = F[n] / F[m];"},
234   {"", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110", "F[n] = F[m] * F[0] + F[n];"},
235   {"", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100", "T = F[n] == F[m] ? 1 : 0;"},
236   {"", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101", "T = F[n] > F[m] ? 1 : 0;"},
237   {"", "", "fneg <FREG_N>", "1111nnnn01001101", "F[n] = -F[n];"},
238   {"", "", "fabs <FREG_N>", "1111nnnn01011101", "F[n] = fabs (F[n]);"},
239   {"", "", "fsqrt <FREG_N>", "1111nnnn01101101", "F[n] = sqrt (F[n]);"},
240   {"", "", "float FPUL,<FREG_N>", "1111nnnn00101101", "F[n] = (float)FPUL;"},
241   {"", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101", "if (F[n] != F[n]) /* NaN */ FPUL = 0x80000000; else FPUL = (int)F[n];"},
242   {"", "", "ftst/nan <FREG_N>", "1111nnnn01111101", "T = isnan (F[n]);"},
243   {"", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101", "*(int *)buf = FPUL; F[n] = *(float *)buf;"},
244   {"", "", "flds <FREG_N>,FPUL", "1111nnnn00011101", "*(float *)buf = F[n]; FPUL = *(int *)buf;"},
245   {"", "", "lds <REG_N>,FPUL", "0100nnnn01011010", "FPUL = R[n];"},
246   {"", "", "sts FPUL,<REG_N>", "0000nnnn01011010", "R[n] = FPUL;"},
247   {"", "", "lds <REG_N>,FPSCR", "0100nnnn01101010", "*(int *)buf = R[n]; FPSCR = *(float *)buf;"},
248   {"", "", "sts FPSCR,<REG_N>", "0000nnnn01101010", "*(float *)buf = FPSCR; R[n] = *(int *)buf;"},
249   {"","","lds.l @<REG_N>+,FPUL", "0100nnnn01010110", "FPUL = RLAT(R[n]);R[n]+=4;"},
250   {"","","lds.l @<REG_N>+,FPSCR", "0100nnnn01100110", "*(int *)buf = RLAT(R[n]); FPSCR = *(float *)buf; R[n]+=4;"},
251   {"","","sts.l FPUL,@-<REG_N>", "0100nnnn01010010", "R[n]-=4;WLAT(R[n],FPUL);"},
252   {"","","sts.l FPSCR,@-<REG_N>", "0100nnnn01100010", "R[n]-=4;*(float *)buf = FPSCR; WLAT(R[n],*(int *)buf);"},
253 /* end-sanitize-sh3e */
254
255   {0, 0}};
256
257 /* Tables of things to put into enums for sh-opc.h */
258 static char *nibble_type_list[] =
259 {
260   "HEX_0",
261   "HEX_1",
262   "HEX_2",
263   "HEX_3",
264   "HEX_4",
265   "HEX_5",
266   "HEX_6",
267   "HEX_7",
268   "HEX_8",
269   "HEX_9",
270   "HEX_A",
271   "HEX_B",
272   "HEX_C",
273   "HEX_D",
274   "HEX_E",
275   "HEX_F",
276   "REG_N",
277   "REG_M",
278   "BRANCH_12",
279   "BRANCH_8",
280   "DISP_8",
281   "DISP_4",
282   "IMM_4",
283   "IMM_4BY2",
284   "IMM_4BY4",
285   "PCRELIMM_8BY2",
286   "PCRELIMM_8BY4",
287   "IMM_8",
288   "IMM_8BY2",
289   "IMM_8BY4",
290   0
291 };
292 static
293 char *arg_type_list[] =
294 {
295   "A_END",
296   "A_BDISP12",
297   "A_BDISP8",
298   "A_DEC_M",
299   "A_DEC_N",
300   "A_DISP_GBR",
301   "A_DISP_PC",
302   "A_DISP_REG_M",
303   "A_DISP_REG_N",
304   "A_GBR",
305   "A_IMM",
306   "A_INC_M",
307   "A_INC_N",
308   "A_IND_M",
309   "A_IND_N",
310   "A_IND_R0_REG_M",
311   "A_IND_R0_REG_N",
312   "A_MACH",
313   "A_MACL",
314   "A_PR",
315   "A_R0",
316   "A_R0_GBR",
317   "A_REG_M",
318   "A_REG_N",
319   "A_SR",
320   "A_VBR",
321   "A_SSR",
322   "A_SPC",
323   0,
324 };
325
326 static void
327 make_enum_list (name, s)
328      char *name;
329      char **s;
330 {
331   int i = 1;
332   printf ("typedef enum {\n");
333   while (*s)
334     {
335       printf ("\t%s,\n", *s);
336       s++;
337       i++;
338     }
339   printf ("} %s;\n", name);
340 }
341
342 static int
343 qfunc (a, b)
344      op *a;
345      op *b;
346 {
347   char bufa[9];
348   char bufb[9];
349   memcpy (bufa, a->code, 4);
350   memcpy (bufa + 4, a->code + 12, 4);
351   bufa[8] = 0;
352
353   memcpy (bufb, b->code, 4);
354   memcpy (bufb + 4, b->code + 12, 4);
355   bufb[8] = 0;
356   return (strcmp (bufa, bufb));
357 }
358
359 static void
360 sorttab ()
361 {
362   op *p = tab;
363   int len = 0;
364
365   while (p->name)
366     {
367       p++;
368       len++;
369     }
370   qsort (tab, len, sizeof (*p), qfunc);
371 }
372
373 static void
374 printonmatch (ptr, a, rep)
375      char **ptr;
376      char *a;
377      char *rep;
378 {
379   int l = strlen (a);
380   if (strncmp (*ptr, a, l) == 0)
381     {
382       printf ("%s", rep);
383       *ptr += l;
384       if (**ptr)
385         printf (",");
386     }
387 }
388
389
390 static 
391 void
392 think (o)
393      op *o;
394 {
395   char *n;
396   char *p;
397
398   printf ("{\"");
399   n = o->name;
400   while (*n && *n != ' ')
401     {
402       printf ("%c", *n);
403       n++;
404     }
405   printf ("\",{");
406
407   p = n;
408
409   if (!*p)
410     {
411       printf ("0");
412     }
413   while (*p)
414     {
415       while (*p == ',' || *p == ' ')
416         p++;
417       printonmatch (&p, "#<imm>", "A_IMM");
418       printonmatch (&p, "R0", "A_R0");
419       printonmatch (&p, "<REG_N>", "A_REG_N");
420       printonmatch (&p, "@<REG_N>+", "A_INC_N");
421       printonmatch (&p, "@<REG_N>", "A_IND_N");
422       printonmatch (&p, "@-<REG_N>", "A_DEC_N");
423       printonmatch (&p, "<REG_M>", " A_REG_M");
424       printonmatch (&p, "@<REG_M>+", "A_INC_M");
425       printonmatch (&p, "@<REG_M>", "A_IND_M");
426       printonmatch (&p, "@-<REG_M>", "A_DEC_M");
427       printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
428       printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
429       printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
430       printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
431       printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
432       printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
433       printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
434       printonmatch (&p, "<bdisp8>", "A_BDISP8");
435       printonmatch (&p, "<bdisp12>", "A_BDISP12");
436       printonmatch (&p, "SR", "A_SR");
437       printonmatch (&p, "GBR", "A_GBR");
438       printonmatch (&p, "VBR", "A_VBR");
439       printonmatch (&p, "SSR", "A_SSR");
440       printonmatch (&p, "SPC", "A_SPC");
441       printonmatch (&p, "MACH", "A_MACH");
442       printonmatch (&p, "MACL", "A_MACL");
443       printonmatch (&p, "PR", "A_PR");
444
445     }
446   printf ("},{");
447
448   p = o->code;
449   while (*p)
450     {
451       printonmatch (&p, "0000", "HEX_0");
452       printonmatch (&p, "0001", "HEX_1");
453       printonmatch (&p, "0010", "HEX_2");
454       printonmatch (&p, "0011", "HEX_3");
455       printonmatch (&p, "0100", "HEX_4");
456       printonmatch (&p, "0101", "HEX_5");
457       printonmatch (&p, "0110", "HEX_6");
458       printonmatch (&p, "0111", "HEX_7");
459
460       printonmatch (&p, "1000", "HEX_8");
461       printonmatch (&p, "1001", "HEX_9");
462       printonmatch (&p, "1010", "HEX_A");
463       printonmatch (&p, "1011", "HEX_B");
464       printonmatch (&p, "1100", "HEX_C");
465       printonmatch (&p, "1101", "HEX_D");
466       printonmatch (&p, "1110", "HEX_E");
467       printonmatch (&p, "1111", "HEX_F");
468       printonmatch (&p, "i8*1....", "IMM_8");
469       printonmatch (&p, "i4*1", "IMM_4");
470       printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
471       printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
472       printonmatch (&p, "i8*2....", "IMM_8BY2");
473       printonmatch (&p, "i4*2", "IMM_4BY2");
474       printonmatch (&p, "i8*4....", "IMM_8BY4");
475       printonmatch (&p, "i4*4", "IMM_4BY4");
476       printonmatch (&p, "i12.........", "BRANCH_12");
477       printonmatch (&p, "i8p1....", "BRANCH_8");
478       printonmatch (&p, "nnnn", "REG_N");
479       printonmatch (&p, "mmmm", "REG_M");
480
481     }
482   printf ("}},\n");
483 }
484
485 static void
486 gengastab ()
487 {
488   op *p;
489   sorttab ();
490   for (p = tab; p->name; p++)
491     {
492       printf ("%s %-30s\n", p->code, p->name);
493     }
494
495
496 }
497
498
499 static void
500 genopc ()
501 {
502   op *p;
503   make_enum_list ("sh_nibble_type", nibble_type_list);
504   make_enum_list ("sh_arg_type", arg_type_list);
505
506   printf ("typedef struct {\n");
507   printf ("char *name;\n");
508   printf ("sh_arg_type arg[3];\n");
509   printf ("sh_nibble_type nibbles[4];\n");
510   printf ("} sh_opcode_info;\n");
511   printf ("#ifdef DEFINE_TABLE\n");
512   printf ("sh_opcode_info sh_table[]={\n");
513   for (p = tab; p->name; p++)
514     {
515       printf ("\n/* %s %-20s*/", p->code, p->name);
516       think (p);
517     }
518   printf ("0};\n");
519   printf ("#endif\n");
520 }
521
522
523
524
525
526
527 /* Convert a string of 4 binary digits into an int */
528
529 static
530 int
531 bton (s)
532      char *s;
533
534 {
535   int n = 0;
536   int v = 8;
537   while (v)
538     {
539       if (*s == '1')
540         n |= v;
541       v >>= 1;
542       s++;
543     }
544   return n;
545 }
546
547 static unsigned char table[1 << 16];
548
549 /* Take an opcode expand all varying fields in it out and fill all the
550   right entries in 'table' with the opcode index*/
551
552 static void
553 expand_opcode (shift, val, i, s)
554      int shift;
555      int val;
556      int i;
557      char *s;
558 {
559   int j;
560
561   if (*s == 0)
562     {
563       table[val] = i;
564     }
565   else
566     {
567       switch (s[0])
568         {
569
570         case '0':
571         case '1':
572           {
573
574             int n = bton (s);
575             if (n >= 0)
576               {
577                 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
578               }
579             break;
580           }
581         case 'n':
582         case 'm':
583           for (j = 0; j < 16; j++)
584             {
585               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
586
587             }
588           break;
589
590         default:
591           for (j = 0; j < (1 << (shift + 4)); j++)
592             {
593               table[val | j] = i;
594             }
595         }
596     }
597 }
598
599 /* Print the jump table used to index an opcode into a switch
600    statement entry. */
601
602 static void
603 dumptable ()
604 {
605   int lump = 256;
606   int online = 16;
607
608   int i = 0;
609
610   while (i < 1 << 16)
611     {
612       int j = 0;
613
614       printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
615
616       while (j < lump)
617         {
618           int k = 0;
619           while (k < online)
620             {
621               printf ("%2d", table[i + j + k]);
622               if (j + k < lump)
623                 printf (",");
624
625               k++;
626             }
627           j += k;
628           printf ("\n");
629         }
630       i += j;
631       printf ("};\n");
632     }
633
634 }
635
636
637 static void
638 filltable ()
639 {
640   op *p;
641   int index = 1;
642
643   sorttab ();
644   for (p = tab; p->name; p++)
645     {
646       p->index = index++;
647       expand_opcode (12, 0, p->index, p->code);
648     }
649 }
650
651 static void
652 gensim ()
653 {
654   op *p;
655   int j;
656
657   printf ("{\n");
658 /* start-sanitize-sh3e */
659   printf("char buf[4];\n");
660 /* end-sanitize-sh3e */
661   printf ("switch (jump_table[iword]) {\n");
662
663   for (p = tab; p->name; p++)
664     {
665       int sextbit = -1;
666       int needm = 0;
667       int needn = 0;
668       
669       char *s = p->code;
670
671       printf ("/* %s %s */\n", p->name, p->code);
672       printf ("case %d:      \n", p->index);
673
674       printf ("{\n");
675       while (*s)
676         {
677           switch (*s)
678             {
679             case '0':
680             case '1':
681             case '.':
682               s += 4;
683               break;
684             case 'n':
685               printf ("int n =  (iword >>8) & 0xf;\n");
686               needn = 1;
687               s += 4;
688               break;
689             case 'm':
690               printf ("int m =  (iword >>4) & 0xf;\n");
691               needm = 1;
692               s += 4;
693
694               break;
695
696             case 'i':
697               printf ("int i = (iword & 0x");
698
699               switch (s[1])
700                 {
701                 case '4':
702                   printf ("f");
703                   break;
704                 case '8':
705                   printf ("ff");
706                   break;
707                 case '1':
708                   sextbit = 12;
709
710                   printf ("fff");
711                   break;
712                 }
713               printf (")");
714
715               switch (s[3])
716                 {
717                 case '1':
718                   break;
719                 case '2':
720                   printf ("<<1");
721                   break;
722                 case '4':
723                   printf ("<<2");
724                   break;
725                 }
726               printf (";\n");
727               s += 4;
728             }
729         }
730       if (sextbit > 0)
731         {
732           printf ("i = (i ^ (1<<%d))-(1<<%d);\n", sextbit - 1, sextbit - 1);
733         }
734       if (needm && needn)
735         printf("TB(m,n);");  
736       else if (needm)
737         printf("TL(m);");
738       else if (needn)
739         printf("TL(n);");
740       for (j = 0; j < 10; j++)
741         {
742           if (p->stuff[j])
743             {
744               printf ("%s\n", p->stuff[j]);
745             }
746         }
747
748       
749       {
750         /* Do the defs and refs */
751         char *r;
752         for (r = p->refs; *r; r++) {
753          if (*r == '0') printf("CREF(0);\n"); 
754          if (*r == 'n') printf("CREF(n);\n"); 
755          if (*r == 'm') printf("CREF(m);\n"); 
756          
757         }
758         for (r = p->defs; *r; r++) 
759           {
760          if (*r == '0') printf("CDEF(0);\n"); 
761          if (*r == 'n') printf("CDEF(n);\n"); 
762          if (*r == 'm') printf("CDEF(m);\n"); 
763          
764         }
765
766       }
767       printf ("break;\n");
768       printf ("}\n");
769     }
770   printf("default:\n{\nsaved_state.asregs.exception = SIGILL;\n}\n");
771   printf ("}\n}\n");
772 }
773
774
775 static void
776 gendefines ()
777 {
778   op *p;
779   filltable();
780   for (p = tab; p->name; p++)
781     {
782       char *s = p->name;
783       printf ("#define OPC_");
784       while (*s) {
785         if (isupper(*s)) 
786           *s = tolower(*s);
787         if (isalpha(*s)) printf("%c", *s);
788         if (*s == ' ') printf("_");
789         if (*s == '@') printf("ind_");
790         if (*s == ',') printf("_");
791         s++;
792       }
793       printf(" %d\n",p->index);
794     }
795 }
796
797 int
798 main (ac, av)
799      int ac;
800      char **av;
801 {
802   if (ac > 1)
803     {
804       if (strcmp (av[1], "-t") == 0)
805         {
806           gengastab ();
807         }
808       else if (strcmp (av[1], "-d") == 0)
809         {
810           gendefines ();
811         }
812       else if (strcmp (av[1], "-s") == 0)
813         {
814           filltable ();
815           dumptable ();
816
817         }
818       else if (strcmp (av[1], "-x") == 0)
819         {
820           filltable ();
821           gensim ();
822         }
823     }
824   else
825     {
826       genopc ();
827     }
828   return 0;
829 }