Initial creation of sourceware repository
[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 #define MAX_NR_STUFF 20
35
36 typedef struct
37 {
38   char *defs;
39   char *refs;
40   char *name;
41   char *code;
42   char *stuff[MAX_NR_STUFF];
43   int index;
44 }
45
46 op;
47
48
49 op tab[] =
50 {
51
52   { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
53     "R[n] += SEXT(i);",
54     "if (i == 0) {",
55     "  UNDEF(n); /* see #ifdef PARANOID */",
56     "  break;",
57     "}",
58   },
59   { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
60     "R[n] += R[m];",
61   },
62
63   { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
64     "ult = R[n] + T;",
65     "SET_SR_T (ult < R[n]);",
66     "R[n] = ult + R[m];",
67     "SET_SR_T (T || (R[n] < ult));",
68   },
69
70   { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
71     "ult = R[n] + R[m];",
72     "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
73     "R[n] = ult;",
74   },
75
76   { "0", "", "and #<imm>,R0", "11001001i8*1....",
77     "R0 &= i;",
78   },
79   { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
80     "R[n] &= R[m];",
81   },
82   { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
83     "MA (1);",
84     "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
85   },
86
87   { "", "", "bf <bdisp8>", "10001011i8p1....",
88     "if (!T) {",
89     "  nia = PC + 4 + (SEXT(i) * 2);",
90     "  cycles += 2;",
91     "}",
92   },
93
94   { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95     "if (!T) {",
96     "  nia = PC + 4 + (SEXT (i) * 2);",
97     "  cycles += 2;",
98     "  Delay_Slot (PC + 2);",
99     "}",
100   },
101
102   { "", "", "bra <bdisp12>", "1010i12.........",
103     "nia = PC + 4 + (SEXT12 (i) * 2);",
104     "Delay_Slot (PC + 2);",
105   },
106
107   { "", "n", "braf <REG_N>", "0000nnnn00100011",
108     "nia = PC + 4 + R[n];",
109     "Delay_Slot (PC + 2);",
110   },
111
112   { "", "", "bsr <bdisp12>", "1011i12.........",
113     "PR = PC + 4;",
114     "nia = PC + 4 + (SEXT12 (i) * 2);",
115     "Delay_Slot (PC + 2);",
116   },
117
118   { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
119     "PR = PC + 4;",
120     "nia = PC + 4 + R[n];",
121     "Delay_Slot (PC + 2);",
122   },
123
124   { "", "", "bt <bdisp8>", "10001001i8p1....",
125     "if (T) {",
126     "  nia = PC + 4 + (SEXT (i) * 2);",
127     "  cycles += 2;",
128     "}",
129   },
130
131   { "", "", "bt.s <bdisp8>", "10001101i8p1....",
132     "if (T) {",
133     "  nia = PC + 4 + (SEXT (i) * 2);",
134     "  cycles += 2;",
135     "  Delay_Slot (PC + 2);",
136     "}",
137   },
138
139   { "", "", "clrmac", "0000000000101000",
140     "MACH = 0;",
141     "MACL = 0;",
142   },
143
144   { "", "", "clrs", "0000000001001000",
145     "SET_SR_S (0);",
146   },
147
148   { "", "", "clrt", "0000000000001000",
149     "SET_SR_T (0);",
150   },
151
152   { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
153     "SET_SR_T (R0 == SEXT (i));",
154   },
155   { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
156     "SET_SR_T (R[n] == R[m]);",
157   },
158   { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
159     "SET_SR_T (R[n] >= R[m]);",
160   },
161   { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
162     "SET_SR_T (R[n] > R[m]);",
163   },
164   { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
165     "SET_SR_T (UR[n] > UR[m]);",
166   },
167   { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
168     "SET_SR_T (UR[n] >= UR[m]);",
169   },
170   { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
171     "SET_SR_T (R[n] > 0);",
172   },
173   { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
174     "SET_SR_T (R[n] >= 0);",
175   },
176   { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
177     "ult = R[n] ^ R[m];",
178     "SET_SR_T (((ult & 0xff000000) == 0)",
179     "          | ((ult & 0xff0000) == 0)",
180     "          | ((ult & 0xff00) == 0)",
181     "          | ((ult & 0xff) == 0));",
182   },
183
184   { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
185     "SET_SR_Q ((R[n] & sbit) != 0);",
186     "SET_SR_M ((R[m] & sbit) != 0);",
187     "SET_SR_T (M != Q);",
188   },
189
190   { "", "", "div0u", "0000000000011001",
191     "SET_SR_M (0);",
192     "SET_SR_Q (0);",
193     "SET_SR_T (0);",
194   },
195
196   { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
197     "div1 (R, m, n/*, T*/);",
198   },
199
200   { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
201     "dmul (1/*signed*/, R[n], R[m]);",
202   },
203
204   { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
205     "dmul (0/*unsigned*/, R[n], R[m]);",
206   },
207
208   { "n", "n", "dt <REG_N>", "0100nnnn00010000",
209     "R[n]--;",
210     "SET_SR_T (R[n] == 0);",
211   },
212
213   { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
214     "R[n] = SEXT (R[m]);",
215   },
216   { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
217     "R[n] = SEXTW (R[m]);",
218   },
219
220   { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
221     "R[n] = (R[m] & 0xff);",
222   },
223   { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
224     "R[n] = (R[m] & 0xffff);",
225   },
226
227   /* sh3e */
228   { "", "", "fabs <FREG_N>", "1111nnnn01011101",
229     "FP_UNARY (n, fabs);",
230     "/* FIXME: FR(n) &= 0x7fffffff; */",
231   },
232
233   /* sh3e */
234   { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
235     "FP_OP (n, +, m);",
236   },
237
238   /* sh3e */
239   { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
240     "FP_CMP (n, ==, m);",
241   },
242   /* sh3e */
243   { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
244     "FP_CMP (n, >, m);",
245   },
246
247   /* sh3e */
248   { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
249     "FP_OP (n, /, m);",
250     "/* FIXME: check for DP and (n & 1) == 0? */",
251   },
252
253   /* sh3e */
254   { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
255     "SET_FR (n, (float)0.0);",
256     "/* FIXME: check for DP and (n & 1) == 0? */",
257   },
258
259   /* sh3e */
260   { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
261     "SET_FR (n, (float)1.0);",
262     "/* FIXME: check for DP and (n & 1) == 0? */",
263   },
264
265   /* sh3e */
266   { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
267     "char buf[4];",
268     "*(float *)buf = FR(n);",
269     "FPUL = *(int *)buf;",
270   },
271
272   /* sh3e */
273   { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
274     "{",
275     "  SET_FR (n, (float)FPUL);",
276     "}",
277   },
278
279   /* sh3e */
280   { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
281     "SET_FR (n, FR(m) * FR(0) + FR(n));",
282     "/* FIXME: check for DP and (n & 1) == 0? */",
283   },
284
285   /* sh3e */
286   { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
287     "{",
288     "  SET_FR (n, FR (m));",
289     "}",
290   },
291   /* sh3e */
292   { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
293     "{",
294     "  MA (1);",
295     "  WLAT (R[n], FI(m));",
296     "}",
297   },
298   /* sh3e */
299   { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
300     "{",
301     "  MA (1);",
302     "  SET_FI(n, RLAT(R[m]));",
303     "}",
304   },
305   /* sh3e */
306   { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
307     "{",
308     "  MA (1);",
309     "  SET_FI (n, RLAT (R[m]));",
310     "  R[m] += 4;",
311     "}",
312   },
313   /* sh3e */
314   { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
315     "{",
316     "  MA (1);",
317     "  R[n] -= 4;",
318     "  WLAT (R[n], FI(m));",
319     "}",
320   },
321   /* sh3e */
322   { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
323     "{",
324     "  MA (1);",
325     "  SET_FI(n, RLAT(R[0] + R[m]));",
326     "}",
327   },
328   /* sh3e */
329   { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
330     "{",
331     "  MA (1);",
332     "  WLAT((R[0]+R[n]), FI(m));",
333     "}",
334   },
335
336   /* sh3e */
337   { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
338     "FP_OP(n, *, m);",
339   },
340
341   /* sh3e */
342   { "", "", "fneg <FREG_N>", "1111nnnn01001101",
343     "FP_UNARY(n, -);",
344   },
345
346   /* sh3e */
347   { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
348     "FP_UNARY(n, sqrt);",
349   },
350
351   /* sh3e */
352   { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
353     "FP_OP(n, -, m);",
354   },
355
356   /* sh3e */
357   { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
358     "if (FR(n) != FR(n)) /* NaN */",
359     "  FPUL = 0x80000000;",
360     "else",
361     "  FPUL = (int)FR(n);",
362   },
363
364   /* sh3e */
365   { "", "", "ftst/nan <FREG_N>", "1111nnnn01111101",
366     "SET_SR_T (isnan (FR(n)));",
367   },
368   /* sh3e */
369   { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
370     "char buf[4];",
371     "*(int *)buf = FPUL;",
372     "SET_FR (n, *(float *)buf);",
373   },
374
375   { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
376     "nia = R[n];",
377     "Delay_Slot (PC + 2);",
378   },
379
380   { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
381     "PR = PC + 4;",
382     "nia = R[n];",
383     "if (~doprofile)",
384     "  gotcall (PR, nia);",
385     "Delay_Slot (PC + 2);",
386   },
387
388   { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
389     "GBR = R[n];",
390     "/* FIXME: user mode */",
391   },
392   { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
393     "SET_SR (R[n]);",
394     "/* FIXME: user mode */",
395   },
396   { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
397     "VBR = R[n];",
398     "/* FIXME: user mode */",
399   },
400   { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
401     "SSR = R[n];",
402     "/* FIXME: user mode */",
403   },
404   { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
405     "SPC = R[n];",
406     "/* FIXME: user mode */",
407   },
408   { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
409     "SET_Rn_BANK (0, R[n]);",
410     "/* FIXME: user mode */",
411   },
412   { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
413     "SET_Rn_BANK (1, R[n]);",
414     "/* FIXME: user mode */",
415   },
416   { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
417     "SET_Rn_BANK (2, R[n]);",
418     "/* FIXME: user mode */",
419   },
420   { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
421     "SET_Rn_BANK (3, R[n]);",
422     "/* FIXME: user mode */",
423   },
424   { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
425     "SET_Rn_BANK (4, R[n]);",
426     "/* FIXME: user mode */",
427   },
428   { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
429     "SET_Rn_BANK (5, R[n]);",
430     "/* FIXME: user mode */",
431   },
432   { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
433     "SET_Rn_BANK (6, R[n]);",
434     "/* FIXME: user mode */",
435   },
436   { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
437     "SET_Rn_BANK (7, R[n]);",
438     "/* FIXME: user mode */",
439   },
440   { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
441     "MA (1);",
442     "GBR = RLAT (R[n]);",
443     "R[n] += 4;",
444     "/* FIXME: user mode */",
445   },
446   { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
447     "MA (1);",
448     "SET_SR (RLAT (R[n]));",
449     "R[n] += 4;",
450     "/* FIXME: user mode */",
451   },
452   { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
453     "MA (1);",
454     "VBR = RLAT (R[n]);",
455     "R[n] += 4;",
456     "/* FIXME: user mode */",
457   },
458   { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
459     "MA (1);",
460     "SSR = RLAT (R[n]);",
461     "R[n] += 4;",
462     "/* FIXME: user mode */",
463   },
464   { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
465     "MA (1);",
466     "SPC = RLAT (R[n]);",
467     "R[n] += 4;",
468     "/* FIXME: user mode */",
469   },
470   { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
471     "MA (1);",
472     "SET_Rn_BANK (0, RLAT (R[n]));",
473     "R[n] += 4;",
474     "/* FIXME: user mode */",
475   },
476   { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
477     "MA (1);",
478     "SET_Rn_BANK (1, RLAT (R[n]));",
479     "R[n] += 4;",
480     "/* FIXME: user mode */",
481   },
482   { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
483     "MA (1);",
484     "SET_Rn_BANK (2, RLAT (R[n]));",
485     "R[n] += 4;",
486     "/* FIXME: user mode */",
487   },
488   { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
489     "MA (1);",
490     "SET_Rn_BANK (3, RLAT (R[n]));",
491     "R[n] += 4;",
492     "/* FIXME: user mode */",
493   },
494   { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
495     "MA (1);",
496     "SET_Rn_BANK (4, RLAT (R[n]));",
497     "R[n] += 4;",
498     "/* FIXME: user mode */",
499   },
500   { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
501     "MA (1);",
502     "SET_Rn_BANK (5, RLAT (R[n]));",
503     "R[n] += 4;",
504     "/* FIXME: user mode */",
505   },
506   { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
507     "MA (1);",
508     "SET_Rn_BANK (6, RLAT (R[n]));",
509     "R[n] += 4;",
510     "/* FIXME: user mode */",
511   },
512   { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
513     "MA (1);",
514     "SET_Rn_BANK (7, RLAT (R[n]));",
515     "R[n] += 4;",
516     "/* FIXME: user mode */",
517   },
518
519   /* sh3e */
520   { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
521     "FPUL = R[n];",
522   },
523   /* sh3e */
524   { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
525     "MA (1);",
526     "FPUL = RLAT(R[n]);",
527     "R[n] += 4;",
528   },
529   /* sh3e */
530   { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
531     "SET_FPSCR(R[n]);",
532   },
533   /* sh3e */
534   { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
535     "MA (1);",
536     "SET_FPSCR (RLAT(R[n]));",
537     "R[n] += 4;",
538   },
539
540   { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
541     "MACH = R[n];",
542   },
543   { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
544     "MACL= R[n];",
545   },
546   { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
547     "PR = R[n];",
548   },
549   { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
550     "MA (1);",
551     "MACH = SEXT(RLAT(R[n]));",
552     "R[n]+=4;",
553   },
554   { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
555     "MA (1);",
556     "MACL = RLAT(R[n]);",
557     "R[n]+=4;",
558   },
559   { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
560     "MA (1);",
561     "PR = RLAT(R[n]);",
562     "R[n]+=4;;",
563   },
564
565   { "", "", "ldtlb", "0000000000111000",
566     "/* FIXME: XXX*/ abort();",
567   },
568
569   { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
570     "trap (255,R0,memory,maskl,maskw,little_endian);",
571     "/* FIXME: mac.l support */",
572   },
573
574   { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
575     "macw(R0,memory,n,m);",
576   },
577
578   { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
579     "R[n] = SEXT(i);",
580   },
581   { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
582     "R[n] = R[m];",
583   },
584
585   { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
586     "MA (1);",
587     "R0 = RSBAT (i + GBR);",
588     "L (0);",
589   },
590   { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
591     "MA (1);",
592     "R0 = RSBAT (i + R[m]);",
593     "L (0);",
594   },
595   { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
596     "MA (1);",
597     "R[n] = RSBAT (R0 + R[m]);",
598     "L (n);",
599   },
600   { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
601     "MA (1);",
602     "R[n] = RSBAT (R[m]);",
603     "R[m] += 1;",
604     "L (n);",
605   },
606   { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
607     "MA (1);",
608     "WBAT (R[n], R[m]);",
609   },
610   { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
611     "MA (1);",
612     "WBAT (i + GBR, R0);",
613   },
614   { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
615     "MA (1);",
616     "WBAT (i + R[m], R0);",
617   },
618   { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
619     "MA (1);",
620     "WBAT (R[n] + R0, R[m]);",
621   },
622   { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
623     "MA (1);",
624     "R[n] -= 1;",
625     "WBAT (R[n], R[m]);",
626   },
627   { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
628     "MA (1);",
629     "R[n] = RSBAT (R[m]);",
630     "L (n);",
631   },
632
633   { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
634     "MA (1);",
635     "R0 = RLAT (i + GBR);",
636     "L (0);",
637   },
638   { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
639     "MA (1);",
640     "R[n] = RLAT((PC & ~3) + 4 + i);",
641     "L (n);",
642   },
643   { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
644     "MA (1);",
645     "R[n] = RLAT (i + R[m]);",
646     "L (n);",
647   },
648   { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
649     "MA (1);",
650     "R[n] = RLAT (R0 + R[m]);",
651     "L (n);",
652   },
653   { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
654     "MA (1);",
655     "R[n] = RLAT (R[m]);",
656     "R[m] += 4;",
657     "L (n);",
658   },
659   { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
660     "MA (1);",
661     "R[n] = RLAT (R[m]);",
662     "L (n);",
663   },
664   { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
665     "MA (1);",
666     "WLAT (i + GBR, R0);",
667   },
668   { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
669     "MA (1);",
670     "WLAT (i + R[n], R[m]);",
671   },
672   { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
673     "MA (1);",
674     "WLAT (R0 + R[n], R[m]);",
675   },
676   { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
677     "MA (1) ;",
678     "R[n] -= 4;",
679     "WLAT (R[n], R[m]);",
680   },
681   { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
682     "MA (1);",
683     "WLAT (R[n], R[m]);",
684   },
685
686   { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
687     "MA (1)",
688     ";R0 = RSWAT (i + GBR);",
689     "L (0);",
690   },
691   { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
692     "MA (1);",
693     "R[n] = RSWAT (PC + 4 + i);",
694     "L (n);",
695   },
696   { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
697     "MA (1);",
698     "R0 = RSWAT (i + R[m]);",
699     "L (0);",
700   },
701   { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
702     "MA (1);",
703     "R[n] = RSWAT (R0 + R[m]);",
704     "L (n);",
705   },
706   { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
707     "MA (1);",
708     "R[n] = RSWAT (R[m]);",
709     "R[m] += 2;",
710     "L (n);",
711   },
712   { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
713     "MA (1);",
714     "R[n] = RSWAT (R[m]);",
715     "L (n);",
716   },
717   { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
718     "MA (1);",
719     "WWAT (i + GBR, R0);",
720   },
721   { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
722     "MA (1);",
723     "WWAT (i + R[m], R0);",
724   },
725   { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
726     "MA (1);",
727     "WWAT (R0 + R[n], R[m]);",
728   },
729   { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
730     "MA (1);",
731     "R[n] -= 2;",
732     "WWAT (R[n], R[m]);",
733   },
734   { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
735     "MA (1);",
736     "WWAT (R[n], R[m]);",
737   },
738
739   { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
740     "R0 = ((i + 4 + PC) & ~0x3);",
741   },
742
743   { "n", "", "movt <REG_N>", "0000nnnn00101001",
744     "R[n] = T;",
745   },
746
747   { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
748     "MACL = ((int)R[n]) * ((int)R[m]);",
749   },
750 #if 0
751   { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
752     "MACL = R[n] * R[m];",
753   },
754 #endif
755
756   /* muls.w - see muls */
757   { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
758     "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
759   },
760
761   /* mulu.w - see mulu */
762   { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
763     "MACL = (((unsigned int)(unsigned short)R[n])",
764     "        * ((unsigned int)(unsigned short)R[m]));",
765   },
766
767   { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
768     "R[n] = - R[m];",
769   },
770
771   { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
772     "ult = -T;",
773     "SET_SR_T (ult > 0);",
774     "R[n] = ult - R[m];",
775     "SET_SR_T (T || (R[n] > ult));",
776   },
777
778   { "", "", "nop", "0000000000001001",
779     "/* nop */",
780   },
781
782   { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
783     "R[n] = ~R[m];",
784   },
785
786   { "0", "", "or #<imm>,R0", "11001011i8*1....",
787     "R0 |= i;",
788   },
789   { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
790     "R[n] |= R[m];",
791   },
792   { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
793     "MA (1);",
794     "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
795   },
796
797   { "", "n", "pref @<REG_N>", "0000nnnn10000011",
798     "/* Except for the effect on the cache - which is not simulated -",
799     "   this is like a nop.  */",
800   },
801
802   { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
803     "ult = R[n] < 0;",
804     "R[n] = (R[n] << 1) | T;",
805     "SET_SR_T (ult);",
806   },
807
808   { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
809     "ult = R[n] & 1;",
810     "R[n] = (UR[n] >> 1) | (T << 31);",
811     "SET_SR_T (ult);",
812   },
813
814   { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
815     "SET_SR_T (R[n] < 0);",
816     "R[n] <<= 1;",
817     "R[n] |= T;",
818   },
819
820   { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
821     "SET_SR_T (R[n] & 1);",
822     "R[n] = UR[n] >> 1;",
823     "R[n] |= (T << 31);",
824   },
825
826   { "", "", "rte", "0000000000101011", 
827 #if 0
828     /* SH-[12] */
829     "int tmp = PC;",
830     "nia = RLAT (R[15]) + 2;",
831     "R[15] += 4;",
832     "SET_SR (RLAT (R[15]) & 0x3f3);",
833     "R[15] += 4;",
834     "Delay_Slot (PC + 2);",
835 #else
836     "nia = SPC;",
837     "SET_SR (SSR);",
838     "Delay_Slot (PC + 2);",
839 #endif
840   },
841
842   { "", "", "rts", "0000000000001011",
843     "nia = PR;",
844     "Delay_Slot (PC + 2);",
845   },
846
847   { "", "", "sets", "0000000001011000",
848     "SET_SR_S (1);",
849   },
850
851   { "", "", "sett", "0000000000011000",
852     "SET_SR_T (1);",
853   },
854
855   { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
856     "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
857   },
858
859   { "n", "n", "shal <REG_N>", "0100nnnn00100000",
860     "SET_SR_T (R[n] < 0);",
861     "R[n] <<= 1;",
862   },
863
864   { "n", "n", "shar <REG_N>", "0100nnnn00100001",
865     "SET_SR_T (R[n] & 1);",
866     "R[n] = R[n] >> 1;",
867   },
868
869   { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
870     "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
871   },
872
873   { "n", "n", "shll <REG_N>", "0100nnnn00000000",
874     "SET_SR_T (R[n] < 0);",
875     "R[n] <<= 1;",
876   },
877
878   { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
879     "R[n] <<= 2;",
880   },
881   { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
882     "R[n] <<= 8;",
883   },
884   { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
885     "R[n] <<= 16;",
886   },
887
888   { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
889     "SET_SR_T (R[n] & 1);",
890     "R[n] = UR[n] >> 1;",
891   },
892
893   { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
894     "R[n] = UR[n] >> 2;",
895   },
896   { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
897     "R[n] = UR[n] >> 8;",
898   },
899   { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
900     "R[n] = UR[n] >> 16;",
901   },
902
903   { "", "", "sleep", "0000000000011011",
904     "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
905     "nia = PC;",
906   },
907
908   { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
909     "R[n] = GBR;",
910   },
911   { "n", "", "stc SR,<REG_N>",  "0000nnnn00000010",
912     "R[n] = GET_SR ();",
913   },
914   { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
915     "R[n] = VBR;",
916   },
917   { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
918     "R[n] = SSR;",
919   },
920   { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
921     "R[n] = SPC;",
922   },
923   { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
924     "R[n] = Rn_BANK (0);",
925   },
926   { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
927     "R[n] = Rn_BANK (1);",
928   },
929   { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
930     "R[n] = Rn_BANK (2);",
931   },
932   { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
933     "R[n] = Rn_BANK (3);",
934   },
935   { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
936     "R[n] = Rn_BANK (4);",
937   },
938   { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
939     "R[n] = Rn_BANK (5);",
940   },
941   { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
942     "R[n] = Rn_BANK (6);",
943   },
944   { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
945     "R[n] = Rn_BANK (7);",
946   },
947   { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
948     "MA (1);",
949     "R[n] -= 4;",
950     "WLAT (R[n], GBR);;",
951   },
952   { "n", "n", "stc.l SR,@-<REG_N>",  "0100nnnn00000011",
953     "MA (1);",
954     "R[n] -= 4;",
955     "WLAT (R[n], GET_SR());",
956   },
957   { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
958     "MA (1);",
959     "R[n] -= 4;",
960     "WLAT (R[n], VBR);",
961   },
962   { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
963     "MA (1);",
964     "R[n] -= 4;",
965     "WLAT (R[n], SSR);",
966   },
967   { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
968     "MA (1);",
969     "R[n] -= 4;",
970     "WLAT (R[n], SPC);",
971   },
972   { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
973     "MA (1);",
974     "R[n] -= 4;",
975     "WLAT (R[n], Rn_BANK (0));",
976   },
977   { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
978     "MA (1);",
979     "R[n] -= 4;",
980     "WLAT (R[n], Rn_BANK (1));",
981   },
982   { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
983     "MA (1);",
984     "R[n] -= 4;",
985     "WLAT (R[n], Rn_BANK (2));",
986   },
987   { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
988     "MA (1);",
989     "R[n] -= 4;",
990     "WLAT (R[n], Rn_BANK (3));",
991   },
992   { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
993     "MA (1);",
994     "R[n] -= 4;",
995     "WLAT (R[n], Rn_BANK (4));",
996   },
997   { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
998     "MA (1);",
999     "R[n] -= 4;",
1000     "WLAT (R[n], Rn_BANK (5));",
1001   },
1002   { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1003     "MA (1);",
1004     "R[n] -= 4;",
1005     "WLAT (R[n], Rn_BANK (6));",
1006   },
1007   { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1008     "MA (1);",
1009     "R[n] -= 4;",
1010     "WLAT (R[n], Rn_BANK (7));",
1011   },
1012
1013   /* sh3e */
1014   { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1015     "R[n] = FPUL;",
1016   },
1017   /* sh3e */
1018   { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1019     "MA (1);",
1020     "R[n] -= 4;",
1021     "WLAT (R[n], FPUL);",
1022   },
1023   /* sh3e */
1024   { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1025     "R[n] = GET_FPSCR ();",
1026   },
1027   /* sh3e */
1028   { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1029     "MA (1);",
1030     "R[n] -= 4;",
1031     "WLAT (R[n], GET_FPSCR ());",
1032   },
1033
1034   { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1035     "R[n] = MACH;",
1036   },
1037   { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1038     "R[n] = MACL;",
1039   },
1040   { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1041     "R[n] = PR;",
1042   },
1043   { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1044     "MA (1);",
1045     "R[n] -= 4;",
1046     "WLAT (R[n], MACH);",
1047   },
1048   { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1049     "MA (1);",
1050     "R[n] -= 4;",
1051     "WLAT (R[n], MACL);",
1052   },
1053   { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1054     "MA (1);",
1055     "R[n] -= 4;",
1056     "WLAT (R[n], PR);",
1057   },
1058
1059   { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1060     "R[n] -= R[m];",
1061   },
1062
1063   { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1064     "ult = R[n] - T;",
1065     "SET_SR_T (ult > R[n]);",
1066     "R[n] = ult - R[m];",
1067     "SET_SR_T (T || (R[n] > ult));",
1068   },
1069
1070   { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1071     "ult = R[n] - R[m];",
1072     "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1073     "R[n] = ult;",
1074   },
1075
1076   { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1077     "R[n] = ((R[m] & 0xffff0000)",
1078     "        | ((R[m] << 8) & 0xff00)",
1079     "        | ((R[m] >> 8) & 0x00ff));",
1080   },
1081   { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1082     "R[n] = (((R[m] << 16) & 0xffff0000)",
1083     "        | ((R[m] >> 16) & 0x00ffff));",
1084   },
1085
1086   { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1087     "MA (1);",
1088     "ult = RBAT(R[n]);",
1089     "SET_SR_T (ult == 0);",
1090     "WBAT(R[n],ult|0x80);",
1091   },
1092
1093   { "0", "", "trapa #<imm>", "11000011i8*1....", 
1094 #if 0
1095     /* SH-[12] */
1096     "long imm = 0xff & i;",
1097     "if (i==0xc3)",
1098     "  PC-=2;",
1099     "if (i<20||i==34||i==0xc3)",
1100     "  trap(i,R,memory,maskl,maskw,little_endian);",
1101     "else {",
1102     "  R[15]-=4;",
1103     "  WLAT(R[15],GET_SR());",
1104     "  R[15]-=4;",
1105     "  WLAT(R[15],PC+2);",
1106     "  PC=RLAT(VBR+(imm<<2))-2;",
1107     "}",
1108 #else
1109     "if (i == 0xc3)",
1110     "  {",
1111     "    nia = PC;",
1112     "    trap (i, R, memory, maskl, maskw, little_endian);",
1113     "  }",
1114     "else if (i < 20 || i==34 || i==0xc3)",
1115     "  trap (i, R, memory, maskl, maskw, little_endian);",
1116     "else if (!SR_BL) {",
1117     "  /* FIXME: TRA = (imm << 2); */",
1118     "  SSR = GET_SR();",
1119     "  SPC = PC + 2;",
1120     "  SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1121     "  /* FIXME: EXPEVT = 0x00000160; */",
1122     "  nia = VBR + 0x00000100;",
1123     "}",
1124 #endif
1125   },
1126
1127   { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1128     "SET_SR_T ((R[n] & R[m]) == 0);",
1129   },
1130   { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1131     "SET_SR_T ((R0 & i) == 0);",
1132   },
1133   { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1134     "MA (1);",
1135     "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1136   },
1137
1138   { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1139     "R0 ^= i;",
1140   },
1141   { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1142     "R[n] ^= R[m];",
1143   },
1144   { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1145     "MA (1);",
1146     "ult = RBAT (GBR+R0);",
1147     "ult ^= i;",
1148     "WBAT (GBR + R0, ult);",
1149   },
1150
1151   { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1152     "R[n] = (((R[n] >> 16) & 0xffff)",
1153     "        | ((R[m] << 16) & 0xffff0000));",
1154   },
1155
1156   {0, 0}};
1157
1158 /* Tables of things to put into enums for sh-opc.h */
1159 static char *nibble_type_list[] =
1160 {
1161   "HEX_0",
1162   "HEX_1",
1163   "HEX_2",
1164   "HEX_3",
1165   "HEX_4",
1166   "HEX_5",
1167   "HEX_6",
1168   "HEX_7",
1169   "HEX_8",
1170   "HEX_9",
1171   "HEX_A",
1172   "HEX_B",
1173   "HEX_C",
1174   "HEX_D",
1175   "HEX_E",
1176   "HEX_F",
1177   "REG_N",
1178   "REG_M",
1179   "BRANCH_12",
1180   "BRANCH_8",
1181   "DISP_8",
1182   "DISP_4",
1183   "IMM_4",
1184   "IMM_4BY2",
1185   "IMM_4BY4",
1186   "PCRELIMM_8BY2",
1187   "PCRELIMM_8BY4",
1188   "IMM_8",
1189   "IMM_8BY2",
1190   "IMM_8BY4",
1191   0
1192 };
1193 static
1194 char *arg_type_list[] =
1195 {
1196   "A_END",
1197   "A_BDISP12",
1198   "A_BDISP8",
1199   "A_DEC_M",
1200   "A_DEC_N",
1201   "A_DISP_GBR",
1202   "A_DISP_PC",
1203   "A_DISP_REG_M",
1204   "A_DISP_REG_N",
1205   "A_GBR",
1206   "A_IMM",
1207   "A_INC_M",
1208   "A_INC_N",
1209   "A_IND_M",
1210   "A_IND_N",
1211   "A_IND_R0_REG_M",
1212   "A_IND_R0_REG_N",
1213   "A_MACH",
1214   "A_MACL",
1215   "A_PR",
1216   "A_R0",
1217   "A_R0_GBR",
1218   "A_REG_M",
1219   "A_REG_N",
1220   "A_SR",
1221   "A_VBR",
1222   "A_SSR",
1223   "A_SPC",
1224   0,
1225 };
1226
1227 static void
1228 make_enum_list (name, s)
1229      char *name;
1230      char **s;
1231 {
1232   int i = 1;
1233   printf ("typedef enum {\n");
1234   while (*s)
1235     {
1236       printf ("\t%s,\n", *s);
1237       s++;
1238       i++;
1239     }
1240   printf ("} %s;\n", name);
1241 }
1242
1243 static int
1244 qfunc (a, b)
1245      op *a;
1246      op *b;
1247 {
1248   char bufa[9];
1249   char bufb[9];
1250   memcpy (bufa, a->code, 4);
1251   memcpy (bufa + 4, a->code + 12, 4);
1252   bufa[8] = 0;
1253
1254   memcpy (bufb, b->code, 4);
1255   memcpy (bufb + 4, b->code + 12, 4);
1256   bufb[8] = 0;
1257   return (strcmp (bufa, bufb));
1258 }
1259
1260 static void
1261 sorttab ()
1262 {
1263   op *p = tab;
1264   int len = 0;
1265
1266   while (p->name)
1267     {
1268       p++;
1269       len++;
1270     }
1271   qsort (tab, len, sizeof (*p), qfunc);
1272 }
1273
1274 static void
1275 printonmatch (ptr, a, rep)
1276      char **ptr;
1277      char *a;
1278      char *rep;
1279 {
1280   int l = strlen (a);
1281   if (strncmp (*ptr, a, l) == 0)
1282     {
1283       printf ("%s", rep);
1284       *ptr += l;
1285       if (**ptr)
1286         printf (",");
1287     }
1288 }
1289
1290
1291 static 
1292 void
1293 think (o)
1294      op *o;
1295 {
1296   char *n;
1297   char *p;
1298
1299   printf ("{\"");
1300   n = o->name;
1301   while (*n && *n != ' ')
1302     {
1303       printf ("%c", *n);
1304       n++;
1305     }
1306   printf ("\",{");
1307
1308   p = n;
1309
1310   if (!*p)
1311     {
1312       printf ("0");
1313     }
1314   while (*p)
1315     {
1316       while (*p == ',' || *p == ' ')
1317         p++;
1318       printonmatch (&p, "#<imm>", "A_IMM");
1319       printonmatch (&p, "R0", "A_R0");
1320       printonmatch (&p, "<REG_N>", "A_REG_N");
1321       printonmatch (&p, "@<REG_N>+", "A_INC_N");
1322       printonmatch (&p, "@<REG_N>", "A_IND_N");
1323       printonmatch (&p, "@-<REG_N>", "A_DEC_N");
1324       printonmatch (&p, "<REG_M>", " A_REG_M");
1325       printonmatch (&p, "@<REG_M>+", "A_INC_M");
1326       printonmatch (&p, "@<REG_M>", "A_IND_M");
1327       printonmatch (&p, "@-<REG_M>", "A_DEC_M");
1328       printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
1329       printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1330       printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1331       printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1332       printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1333       printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
1334       printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
1335       printonmatch (&p, "<bdisp8>", "A_BDISP8");
1336       printonmatch (&p, "<bdisp12>", "A_BDISP12");
1337       printonmatch (&p, "SR", "A_SR");
1338       printonmatch (&p, "GBR", "A_GBR");
1339       printonmatch (&p, "VBR", "A_VBR");
1340       printonmatch (&p, "SSR", "A_SSR");
1341       printonmatch (&p, "SPC", "A_SPC");
1342       printonmatch (&p, "MACH", "A_MACH");
1343       printonmatch (&p, "MACL", "A_MACL");
1344       printonmatch (&p, "PR", "A_PR");
1345
1346     }
1347   printf ("},{");
1348
1349   p = o->code;
1350   while (*p)
1351     {
1352       printonmatch (&p, "0000", "HEX_0");
1353       printonmatch (&p, "0001", "HEX_1");
1354       printonmatch (&p, "0010", "HEX_2");
1355       printonmatch (&p, "0011", "HEX_3");
1356       printonmatch (&p, "0100", "HEX_4");
1357       printonmatch (&p, "0101", "HEX_5");
1358       printonmatch (&p, "0110", "HEX_6");
1359       printonmatch (&p, "0111", "HEX_7");
1360
1361       printonmatch (&p, "1000", "HEX_8");
1362       printonmatch (&p, "1001", "HEX_9");
1363       printonmatch (&p, "1010", "HEX_A");
1364       printonmatch (&p, "1011", "HEX_B");
1365       printonmatch (&p, "1100", "HEX_C");
1366       printonmatch (&p, "1101", "HEX_D");
1367       printonmatch (&p, "1110", "HEX_E");
1368       printonmatch (&p, "1111", "HEX_F");
1369       printonmatch (&p, "i8*1....", "IMM_8");
1370       printonmatch (&p, "i4*1", "IMM_4");
1371       printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
1372       printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
1373       printonmatch (&p, "i8*2....", "IMM_8BY2");
1374       printonmatch (&p, "i4*2", "IMM_4BY2");
1375       printonmatch (&p, "i8*4....", "IMM_8BY4");
1376       printonmatch (&p, "i4*4", "IMM_4BY4");
1377       printonmatch (&p, "i12.........", "BRANCH_12");
1378       printonmatch (&p, "i8p1....", "BRANCH_8");
1379       printonmatch (&p, "nnnn", "REG_N");
1380       printonmatch (&p, "mmmm", "REG_M");
1381
1382     }
1383   printf ("}},\n");
1384 }
1385
1386 static void
1387 gengastab ()
1388 {
1389   op *p;
1390   sorttab ();
1391   for (p = tab; p->name; p++)
1392     {
1393       printf ("%s %-30s\n", p->code, p->name);
1394     }
1395
1396
1397 }
1398
1399
1400 static void
1401 genopc ()
1402 {
1403   op *p;
1404   make_enum_list ("sh_nibble_type", nibble_type_list);
1405   make_enum_list ("sh_arg_type", arg_type_list);
1406
1407   printf ("typedef struct {\n");
1408   printf ("char *name;\n");
1409   printf ("sh_arg_type arg[3];\n");
1410   printf ("sh_nibble_type nibbles[4];\n");
1411   printf ("} sh_opcode_info;\n");
1412   printf ("#ifdef DEFINE_TABLE\n");
1413   printf ("sh_opcode_info sh_table[]={\n");
1414   for (p = tab; p->name; p++)
1415     {
1416       printf ("\n/* %s %-20s*/", p->code, p->name);
1417       think (p);
1418     }
1419   printf ("0};\n");
1420   printf ("#endif\n");
1421 }
1422
1423
1424
1425
1426
1427
1428 /* Convert a string of 4 binary digits into an int */
1429
1430 static
1431 int
1432 bton (s)
1433      char *s;
1434
1435 {
1436   int n = 0;
1437   int v = 8;
1438   while (v)
1439     {
1440       if (*s == '1')
1441         n |= v;
1442       v >>= 1;
1443       s++;
1444     }
1445   return n;
1446 }
1447
1448 static unsigned char table[1 << 16];
1449
1450 /* Take an opcode expand all varying fields in it out and fill all the
1451   right entries in 'table' with the opcode index*/
1452
1453 static void
1454 expand_opcode (shift, val, i, s)
1455      int shift;
1456      int val;
1457      int i;
1458      char *s;
1459 {
1460   int j;
1461
1462   if (*s == 0)
1463     {
1464       table[val] = i;
1465     }
1466   else
1467     {
1468       switch (s[0])
1469         {
1470
1471         case '0':
1472         case '1':
1473           {
1474
1475             int n = bton (s);
1476             if (n >= 0)
1477               {
1478                 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1479               }
1480             break;
1481           }
1482         case 'n':
1483         case 'm':
1484           for (j = 0; j < 16; j++)
1485             {
1486               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1487
1488             }
1489           break;
1490
1491         default:
1492           for (j = 0; j < (1 << (shift + 4)); j++)
1493             {
1494               table[val | j] = i;
1495             }
1496         }
1497     }
1498 }
1499
1500 /* Print the jump table used to index an opcode into a switch
1501    statement entry. */
1502
1503 static void
1504 dumptable ()
1505 {
1506   int lump = 256;
1507   int online = 16;
1508
1509   int i = 0;
1510
1511   while (i < 1 << 16)
1512     {
1513       int j = 0;
1514
1515       printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1516
1517       while (j < lump)
1518         {
1519           int k = 0;
1520           while (k < online)
1521             {
1522               printf ("%2d", table[i + j + k]);
1523               if (j + k < lump)
1524                 printf (",");
1525
1526               k++;
1527             }
1528           j += k;
1529           printf ("\n");
1530         }
1531       i += j;
1532       printf ("};\n");
1533     }
1534
1535 }
1536
1537
1538 static void
1539 filltable ()
1540 {
1541   op *p;
1542   int index = 1;
1543
1544   sorttab ();
1545   for (p = tab; p->name; p++)
1546     {
1547       p->index = index++;
1548       expand_opcode (12, 0, p->index, p->code);
1549     }
1550 }
1551
1552 static void
1553 gensim ()
1554 {
1555   op *p;
1556   int j;
1557
1558   printf ("{\n");
1559   printf ("  switch (jump_table[iword]) {\n");
1560
1561   for (p = tab; p->name; p++)
1562     {
1563       int sextbit = -1;
1564       int needm = 0;
1565       int needn = 0;
1566       
1567       char *s = p->code;
1568
1569       printf ("  /* %s %s */\n", p->name, p->code);
1570       printf ("  case %d:      \n", p->index);
1571
1572       printf ("    {\n");
1573       while (*s)
1574         {
1575           switch (*s)
1576             {
1577             case '0':
1578             case '1':
1579             case '.':
1580               s += 4;
1581               break;
1582             case 'n':
1583               printf ("      int n = (iword >>8) & 0xf;\n");
1584               needn = 1;
1585               s += 4;
1586               break;
1587             case 'm':
1588               printf ("      int m = (iword >>4) & 0xf;\n");
1589               needm = 1;
1590               s += 4;
1591
1592               break;
1593
1594             case 'i':
1595               printf ("      int i = (iword & 0x");
1596
1597               switch (s[1])
1598                 {
1599                 case '4':
1600                   printf ("f");
1601                   break;
1602                 case '8':
1603                   printf ("ff");
1604                   break;
1605                 case '1':
1606                   sextbit = 12;
1607
1608                   printf ("fff");
1609                   break;
1610                 }
1611               printf (")");
1612
1613               switch (s[3])
1614                 {
1615                 case '1':
1616                   break;
1617                 case '2':
1618                   printf ("<<1");
1619                   break;
1620                 case '4':
1621                   printf ("<<2");
1622                   break;
1623                 }
1624               printf (";\n");
1625               s += 4;
1626             }
1627         }
1628       if (sextbit > 0)
1629         {
1630           printf ("      i = (i ^ (1<<%d))-(1<<%d);\n",
1631                   sextbit - 1, sextbit - 1);
1632         }
1633
1634       if (needm && needn)
1635         printf ("      TB(m,n);\n");  
1636       else if (needm)
1637         printf ("      TL(m);\n");
1638       else if (needn)
1639         printf ("      TL(n);\n");
1640
1641       {
1642         /* Do the refs */
1643         char *r;
1644         for (r = p->refs; *r; r++)
1645           {
1646             if (*r == '0') printf("      CREF(0);\n"); 
1647             if (*r == 'n') printf("      CREF(n);\n"); 
1648             if (*r == 'm') printf("      CREF(m);\n"); 
1649           }
1650       }
1651
1652       printf ("      {\n");
1653       for (j = 0; j < MAX_NR_STUFF; j++)
1654         {
1655           if (p->stuff[j])
1656             {
1657               printf ("        %s\n", p->stuff[j]);
1658             }
1659         }
1660       printf ("      }\n");
1661
1662       {
1663         /* Do the defs */
1664         char *r;
1665         for (r = p->defs; *r; r++) 
1666           {
1667             if (*r == '0') printf("      CDEF(0);\n"); 
1668             if (*r == 'n') printf("      CDEF(n);\n"); 
1669             if (*r == 'm') printf("      CDEF(m);\n"); 
1670           }
1671       }
1672
1673       printf ("      break;\n");
1674       printf ("    }\n");
1675     }
1676   printf ("  default:\n");
1677   printf ("    {\n");
1678   printf ("      saved_state.asregs.exception = SIGILL;\n");
1679   printf ("    }\n");
1680   printf ("  }\n");
1681   printf ("}\n");
1682 }
1683
1684
1685 static void
1686 gendefines ()
1687 {
1688   op *p;
1689   filltable();
1690   for (p = tab; p->name; p++)
1691     {
1692       char *s = p->name;
1693       printf ("#define OPC_");
1694       while (*s) {
1695         if (isupper(*s)) 
1696           *s = tolower(*s);
1697         if (isalpha(*s)) printf("%c", *s);
1698         if (*s == ' ') printf("_");
1699         if (*s == '@') printf("ind_");
1700         if (*s == ',') printf("_");
1701         s++;
1702       }
1703       printf(" %d\n",p->index);
1704     }
1705 }
1706
1707 int
1708 main (ac, av)
1709      int ac;
1710      char **av;
1711 {
1712   /* verify the table before anything else */
1713   {
1714     op *p;
1715     for (p = tab; p->name; p++)
1716       {
1717         /* check that the code field contains 16 bits */
1718         if (strlen (p->code) != 16)
1719           {
1720             fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1721                      p->code, strlen (p->code), p->name);
1722             abort ();
1723           }
1724       }
1725   }
1726
1727   /* now generate the requested data */
1728   if (ac > 1)
1729     {
1730       if (strcmp (av[1], "-t") == 0)
1731         {
1732           gengastab ();
1733         }
1734       else if (strcmp (av[1], "-d") == 0)
1735         {
1736           gendefines ();
1737         }
1738       else if (strcmp (av[1], "-s") == 0)
1739         {
1740           filltable ();
1741           dumptable ();
1742
1743         }
1744       else if (strcmp (av[1], "-x") == 0)
1745         {
1746           filltable ();
1747           gensim ();
1748         }
1749     }
1750   else
1751     {
1752       genopc ();
1753     }
1754   return 0;
1755 }