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