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