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