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