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