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