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