2003-06-27 Michael Snyder <msnyder@redhat.com>
[platform/upstream/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      used to generate the opcode tables
29
30 */
31
32 #include <stdio.h>
33
34 #define MAX_NR_STUFF 42
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 } op;
45
46
47 op tab[] =
48 {
49
50   { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
51     "R[n] += SEXT(i);",
52     "if (i == 0) {",
53     "  UNDEF(n); /* see #ifdef PARANOID */",
54     "  break;",
55     "}",
56   },
57   { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
58     "R[n] += R[m];",
59   },
60
61   { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
62     "ult = R[n] + T;",
63     "SET_SR_T (ult < R[n]);",
64     "R[n] = ult + R[m];",
65     "SET_SR_T (T || (R[n] < ult));",
66   },
67
68   { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
69     "ult = R[n] + R[m];",
70     "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
71     "R[n] = ult;",
72   },
73
74   { "0", "", "and #<imm>,R0", "11001001i8*1....",
75     "R0 &= i;",
76   },
77   { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
78     "R[n] &= R[m];",
79   },
80   { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
81     "MA (1);",
82     "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
83   },
84
85   { "", "", "bf <bdisp8>", "10001011i8p1....",
86     "if (!T) {",
87     "  SET_NIP (PC + 4 + (SEXT(i) * 2));",
88     "  cycles += 2;",
89     "}",
90   },
91
92   { "", "", "bf.s <bdisp8>", "10001111i8p1....",
93     "if (!T) {",
94     "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
95     "  cycles += 2;",
96     "  Delay_Slot (PC + 2);",
97     "}",
98   },
99
100   { "", "", "bra <bdisp12>", "1010i12.........",
101     "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
102     "cycles += 2;",
103     "Delay_Slot (PC + 2);",
104   },
105
106   { "", "n", "braf <REG_N>", "0000nnnn00100011",
107     "SET_NIP (PC + 4 + R[n]);",
108     "cycles += 2;",
109     "Delay_Slot (PC + 2);",
110   },
111
112   { "", "", "bsr <bdisp12>", "1011i12.........",
113     "PR = PH2T (PC + 4);",
114     "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
115     "cycles += 2;",
116     "Delay_Slot (PC + 2);",
117   },
118
119   { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
120     "PR = PH2T (PC) + 4;",
121     "SET_NIP (PC + 4 + R[n]);",
122     "cycles += 2;",
123     "Delay_Slot (PC + 2);",
124   },
125
126   { "", "", "bt <bdisp8>", "10001001i8p1....",
127     "if (T) {",
128     "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
129     "  cycles += 2;",
130     "}",
131   },
132
133   { "", "", "bt.s <bdisp8>", "10001101i8p1....",
134     "if (T) {",
135     "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
136     "  cycles += 2;",
137     "  Delay_Slot (PC + 2);",
138     "}",
139   },
140
141   { "", "", "clrmac", "0000000000101000",
142     "MACH = 0;",
143     "MACL = 0;",
144   },
145
146   { "", "", "clrs", "0000000001001000",
147     "SET_SR_S (0);",
148   },
149
150   { "", "", "clrt", "0000000000001000",
151     "SET_SR_T (0);",
152   },
153
154   { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
155     "SET_SR_T (R0 == SEXT (i));",
156   },
157   { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
158     "SET_SR_T (R[n] == R[m]);",
159   },
160   { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
161     "SET_SR_T (R[n] >= R[m]);",
162   },
163   { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
164     "SET_SR_T (R[n] > R[m]);",
165   },
166   { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
167     "SET_SR_T (UR[n] > UR[m]);",
168   },
169   { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
170     "SET_SR_T (UR[n] >= UR[m]);",
171   },
172   { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
173     "SET_SR_T (R[n] > 0);",
174   },
175   { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
176     "SET_SR_T (R[n] >= 0);",
177   },
178   { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
179     "ult = R[n] ^ R[m];",
180     "SET_SR_T (((ult & 0xff000000) == 0)",
181     "          | ((ult & 0xff0000) == 0)",
182     "          | ((ult & 0xff00) == 0)",
183     "          | ((ult & 0xff) == 0));",
184   },
185
186   { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
187     "SET_SR_Q ((R[n] & sbit) != 0);",
188     "SET_SR_M ((R[m] & sbit) != 0);",
189     "SET_SR_T (M != Q);",
190   },
191
192   { "", "", "div0u", "0000000000011001",
193     "SET_SR_M (0);",
194     "SET_SR_Q (0);",
195     "SET_SR_T (0);",
196   },
197
198   { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
199     "div1 (R, m, n/*, T*/);",
200   },
201
202   { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
203     "dmul (1/*signed*/, R[n], R[m]);",
204   },
205
206   { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
207     "dmul (0/*unsigned*/, R[n], R[m]);",
208   },
209
210   { "n", "n", "dt <REG_N>", "0100nnnn00010000",
211     "R[n]--;",
212     "SET_SR_T (R[n] == 0);",
213   },
214
215   { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
216     "R[n] = SEXT (R[m]);",
217   },
218   { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
219     "R[n] = SEXTW (R[m]);",
220   },
221
222   { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
223     "R[n] = (R[m] & 0xff);",
224   },
225   { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
226     "R[n] = (R[m] & 0xffff);",
227   },
228
229   /* sh2e */
230   { "", "", "fabs <FREG_N>", "1111nnnn01011101",
231     "FP_UNARY (n, fabs);",
232     "/* FIXME: FR(n) &= 0x7fffffff; */",
233   },
234
235   /* sh2e */
236   { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
237     "FP_OP (n, +, m);",
238   },
239
240   /* sh2e */
241   { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
242     "FP_CMP (n, ==, m);",
243   },
244   /* sh2e */
245   { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
246     "FP_CMP (n, >, m);",
247   },
248
249   /* sh4 */
250   { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
251     "if (! FPSCR_PR || n & 1)",
252     "  RAISE_EXCEPTION (SIGILL);",
253     "else",
254     "{",
255     "  union",
256     "  {",
257     "    int i;",
258     "    float f;",
259     "  } u;",
260     "  u.f = DR(n);",
261     "  FPUL = u.i;",
262     "}",
263   },
264
265   /* sh4 */
266   { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
267     "if (! FPSCR_PR || n & 1)",
268     "  RAISE_EXCEPTION (SIGILL);",
269     "else",
270     "{",
271     "  union",
272     "  {",
273     "    int i;",
274     "    float f;",
275     "  } u;",
276     "  u.i = FPUL;",
277     "  SET_DR(n, u.f);",
278     "}",
279   },
280
281   /* sh2e */
282   { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
283     "FP_OP (n, /, m);",
284     "/* FIXME: check for DP and (n & 1) == 0? */",
285   },
286
287   /* sh4 */
288   { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
289     "/* FIXME: not implemented */",
290     "RAISE_EXCEPTION (SIGILL);",
291     "/* FIXME: check for DP and (n & 1) == 0? */",
292   },
293
294   /* sh2e */
295   { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
296     "SET_FR (n, (float)0.0);",
297     "/* FIXME: check for DP and (n & 1) == 0? */",
298   },
299
300   /* sh2e */
301   { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
302     "SET_FR (n, (float)1.0);",
303     "/* FIXME: check for DP and (n & 1) == 0? */",
304   },
305
306   /* sh2e */
307   { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
308     "  union",
309     "  {",
310     "    int i;",
311     "    float f;",
312     "  } u;",
313     "  u.f = FR(n);",
314     "  FPUL = u.i;",
315   },
316
317   /* sh2e */
318   { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
319     /* sh4 */
320     "if (FPSCR_PR)",
321     "  SET_DR (n, (double)FPUL);",
322     "else",
323     "{",
324     "  SET_FR (n, (float)FPUL);",
325     "}",
326   },
327
328   /* sh2e */
329   { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
330     "SET_FR (n, FR(m) * FR(0) + FR(n));",
331     "/* FIXME: check for DP and (n & 1) == 0? */",
332   },
333
334   /* sh2e */
335   { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
336     /* sh4 */
337     "if (FPSCR_SZ) {",
338     "  int ni = XD_TO_XF (n);",
339     "  int mi = XD_TO_XF (m);",
340     "  SET_XF (ni + 0, XF (mi + 0));",
341     "  SET_XF (ni + 1, XF (mi + 1));",
342     "}",
343     "else",
344     "{",
345     "  SET_FR (n, FR (m));",
346     "}",
347   },
348   /* sh2e */
349   { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
350     /* sh4 */
351     "if (FPSCR_SZ) {",
352     "  MA (2);",
353     "  WDAT (R[n], m);",
354     "}",
355     "else",
356     "{",
357     "  MA (1);",
358     "  WLAT (R[n], FI(m));",
359     "}",
360   },
361   /* sh2e */
362   { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
363     /* sh4 */
364     "if (FPSCR_SZ) {",
365     "  MA (2);",
366     "  RDAT (R[m], n);",
367     "}",
368     "else",
369     "{",
370     "  MA (1);",
371     "  SET_FI(n, RLAT(R[m]));",
372     "}",
373   },
374   /* sh2e */
375   { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
376     /* sh4 */
377     "if (FPSCR_SZ) {",
378     "  MA (2);",
379     "  RDAT (R[m], n);",
380     "  R[m] += 8;",
381     "}",
382     "else",
383     "{",
384     "  MA (1);",
385     "  SET_FI (n, RLAT (R[m]));",
386     "  R[m] += 4;",
387     "}",
388   },
389   /* sh2e */
390   { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
391     /* sh4 */
392     "if (FPSCR_SZ) {",
393     "  MA (2);",
394     "  R[n] -= 8;",
395     "  WDAT (R[n], m);",
396     "}",
397     "else",
398     "{",
399     "  MA (1);",
400     "  R[n] -= 4;",
401     "  WLAT (R[n], FI(m));",
402     "}",
403   },
404   /* sh2e */
405   { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
406     /* sh4 */
407     "if (FPSCR_SZ) {",
408     "  MA (2);",
409     "  RDAT (R[0]+R[m], n);",
410     "}",
411     "else",
412     "{",
413     "  MA (1);",
414     "  SET_FI(n, RLAT(R[0] + R[m]));",
415     "}",
416   },
417   /* sh2e */
418   { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
419     /* sh4 */
420     "if (FPSCR_SZ) {",
421     "  MA (2);",
422     "  WDAT (R[0]+R[n], m);",
423     "}",
424     "else",
425     "{",
426     "  MA (1);",
427     "  WLAT((R[0]+R[n]), FI(m));",
428     "}",
429   },
430
431   /* sh4: See fmov instructions above for move to/from extended fp registers */
432
433   /* sh2e */
434   { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
435     "FP_OP(n, *, m);",
436   },
437
438   /* sh2e */
439   { "", "", "fneg <FREG_N>", "1111nnnn01001101",
440     "FP_UNARY(n, -);",
441   },
442
443   /* sh4 */
444   { "", "", "frchg", "1111101111111101",
445     "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
446   },
447
448   /* sh4 */
449   { "", "", "fschg", "1111001111111101",
450     "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
451   },
452
453   /* sh3e */
454   { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
455     "FP_UNARY(n, sqrt);",
456   },
457
458   /* sh2e */
459   { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
460     "FP_OP(n, -, m);",
461   },
462
463   /* sh2e */
464   { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
465     /* sh4 */
466     "if (FPSCR_PR) {",
467     "  if (DR(n) != DR(n)) /* NaN */",
468     "    FPUL = 0x80000000;",
469     "  else",
470     "    FPUL =  (int)DR(n);",
471     "}",
472     "else",
473     "if (FR(n) != FR(n)) /* NaN */",
474     "  FPUL = 0x80000000;",
475     "else",
476     "  FPUL = (int)FR(n);",
477   },
478
479   /* sh2e */
480   { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
481     "  union",
482     "  {",
483     "    int i;",
484     "    float f;",
485     "  } u;",
486     "  u.i = FPUL;",
487     "  SET_FR (n, u.f);",
488   },
489
490   { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
491     "SET_NIP (PT2H (R[n]));",
492     "cycles += 2;",
493     "Delay_Slot (PC + 2);",
494   },
495
496   { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
497     "PR = PH2T (PC + 4);",
498     "if (~doprofile)",
499     "  gotcall (PR, R[n]);",
500     "SET_NIP (PT2H (R[n]));",
501     "cycles += 2;",
502     "Delay_Slot (PC + 2);",
503   },
504
505   { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
506     "CREG (m) = R[n];",
507     "/* FIXME: user mode */",
508   },
509   { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
510     "SET_SR (R[n]);",
511     "/* FIXME: user mode */",
512   },
513   { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
514     "SET_MOD (R[n]);",
515   },
516 #if 0
517   { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
518     "DBR = R[n];",
519     "/* FIXME: user mode */",
520   },
521 #endif
522   { "", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
523     "MA (1);",
524     "CREG (m) = RLAT (R[n]);",
525     "R[n] += 4;",
526     "/* FIXME: user mode */",
527   },
528   { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
529     "MA (1);",
530     "SET_SR (RLAT (R[n]));",
531     "R[n] += 4;",
532     "/* FIXME: user mode */",
533   },
534   { "", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
535     "MA (1);",
536     "SET_MOD (RLAT (R[n]));",
537     "R[n] += 4;",
538   },
539 #if 0
540   { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
541     "MA (1);",
542     "DBR = RLAT (R[n]);",
543     "R[n] += 4;",
544     "/* FIXME: user mode */",
545   },
546 #endif
547
548   /* sh-dsp */
549   { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
550     "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
551   },
552   { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
553     "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
554   },
555
556   { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
557     "SREG (m) = R[n];",
558   },
559   { "", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
560     "MA (1);",
561     "SREG (m) = RLAT(R[n]);",
562     "R[n] += 4;",
563   },
564   /* sh2e / sh-dsp (lds <REG_N>,DSR) */
565   { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
566     "SET_FPSCR(R[n]);",
567   },
568   /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
569   { "", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
570     "MA (1);",
571     "SET_FPSCR (RLAT(R[n]));",
572     "R[n] += 4;",
573   },
574
575   { "", "", "ldtlb", "0000000000111000",
576     "/* FIXME: XXX*/ abort();",
577   },
578
579   { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
580     "trap (255, R0, PC, memory, maskl, maskw, endianw);",
581     "/* FIXME: mac.l support */",
582   },
583
584   { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
585     "macw(R0,memory,n,m,endianw);",
586   },
587
588   { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
589     "R[n] = SEXT(i);",
590   },
591   { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
592     "R[n] = R[m];",
593   },
594
595   { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
596     "MA (1);",
597     "R0 = RSBAT (i + GBR);",
598     "L (0);",
599   },
600   { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
601     "MA (1);",
602     "R0 = RSBAT (i + R[m]);",
603     "L (0);",
604   },
605   { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
606     "MA (1);",
607     "R[n] = RSBAT (R0 + R[m]);",
608     "L (n);",
609   },
610   { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
611     "MA (1);",
612     "R[n] = RSBAT (R[m]);",
613     "R[m] += 1;",
614     "L (n);",
615   },
616   { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
617     "MA (1);",
618     "WBAT (R[n], R[m]);",
619   },
620   { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
621     "MA (1);",
622     "WBAT (i + GBR, R0);",
623   },
624   { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
625     "MA (1);",
626     "WBAT (i + R[m], R0);",
627   },
628   { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
629     "MA (1);",
630     "WBAT (R[n] + R0, R[m]);",
631   },
632   { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
633     "MA (1);",
634     "R[n] -= 1;",
635     "WBAT (R[n], R[m]);",
636   },
637   { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
638     "MA (1);",
639     "R[n] = RSBAT (R[m]);",
640     "L (n);",
641   },
642
643   { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
644     "MA (1);",
645     "R0 = RLAT (i + GBR);",
646     "L (0);",
647   },
648   { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
649     "MA (1);",
650     "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
651     "L (n);",
652   },
653   { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
654     "MA (1);",
655     "R[n] = RLAT (i + R[m]);",
656     "L (n);",
657   },
658   { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
659     "MA (1);",
660     "R[n] = RLAT (R0 + R[m]);",
661     "L (n);",
662   },
663   { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
664     "MA (1);",
665     "R[n] = RLAT (R[m]);",
666     "R[m] += 4;",
667     "L (n);",
668   },
669   { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
670     "MA (1);",
671     "R[n] = RLAT (R[m]);",
672     "L (n);",
673   },
674   { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
675     "MA (1);",
676     "WLAT (i + GBR, R0);",
677   },
678   { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
679     "MA (1);",
680     "WLAT (i + R[n], R[m]);",
681   },
682   { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
683     "MA (1);",
684     "WLAT (R0 + R[n], R[m]);",
685   },
686   { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
687     "MA (1) ;",
688     "R[n] -= 4;",
689     "WLAT (R[n], R[m]);",
690   },
691   { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
692     "MA (1);",
693     "WLAT (R[n], R[m]);",
694   },
695
696   { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
697     "MA (1);",
698     "R0 = RSWAT (i + GBR);",
699     "L (0);",
700   },
701   { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
702     "MA (1);",
703     "R[n] = RSWAT (PH2T (PC + 4 + i));",
704     "L (n);",
705   },
706   { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
707     "MA (1);",
708     "R0 = RSWAT (i + R[m]);",
709     "L (0);",
710   },
711   { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
712     "MA (1);",
713     "R[n] = RSWAT (R0 + R[m]);",
714     "L (n);",
715   },
716   { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
717     "MA (1);",
718     "R[n] = RSWAT (R[m]);",
719     "R[m] += 2;",
720     "L (n);",
721   },
722   { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
723     "MA (1);",
724     "R[n] = RSWAT (R[m]);",
725     "L (n);",
726   },
727   { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
728     "MA (1);",
729     "WWAT (i + GBR, R0);",
730   },
731   { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
732     "MA (1);",
733     "WWAT (i + R[m], R0);",
734   },
735   { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
736     "MA (1);",
737     "WWAT (R0 + R[n], R[m]);",
738   },
739   { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
740     "MA (1);",
741     "R[n] -= 2;",
742     "WWAT (R[n], R[m]);",
743   },
744   { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
745     "MA (1);",
746     "WWAT (R[n], R[m]);",
747   },
748
749   { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
750     "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
751   },
752
753   { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
754     "/* We don't simulate cache, so this insn is identical to mov.  */",
755     "MA (1);",
756     "WLAT (R[n], R[0]);",
757   },
758
759   { "n", "", "movt <REG_N>", "0000nnnn00101001",
760     "R[n] = T;",
761   },
762
763   { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
764     "MACL = ((int)R[n]) * ((int)R[m]);",
765   },
766 #if 0
767   { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
768     "MACL = R[n] * R[m];",
769   },
770 #endif
771
772   /* muls.w - see muls */
773   { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
774     "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
775   },
776
777   /* mulu.w - see mulu */
778   { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
779     "MACL = (((unsigned int)(unsigned short)R[n])",
780     "        * ((unsigned int)(unsigned short)R[m]));",
781   },
782
783   { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
784     "R[n] = - R[m];",
785   },
786
787   { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
788     "ult = -T;",
789     "SET_SR_T (ult > 0);",
790     "R[n] = ult - R[m];",
791     "SET_SR_T (T || (R[n] > ult));",
792   },
793
794   { "", "", "nop", "0000000000001001",
795     "/* nop */",
796   },
797
798   { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
799     "R[n] = ~R[m];",
800   },
801
802   { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
803     "/* FIXME: Not implemented */",
804     "RAISE_EXCEPTION (SIGILL);",
805   },
806
807   { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
808     "/* FIXME: Not implemented */",
809     "RAISE_EXCEPTION (SIGILL);",
810   },
811
812   { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
813     "RSBAT (R[n]); /* Take exceptions like byte load.  */",
814     "/* FIXME: Cache not implemented */",
815   },
816
817   { "0", "", "or #<imm>,R0", "11001011i8*1....",
818     "R0 |= i;",
819   },
820   { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
821     "R[n] |= R[m];",
822   },
823   { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
824     "MA (1);",
825     "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
826   },
827
828   { "", "n", "pref @<REG_N>", "0000nnnn10000011",
829     "/* Except for the effect on the cache - which is not simulated -",
830     "   this is like a nop.  */",
831   },
832
833   { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
834     "ult = R[n] < 0;",
835     "R[n] = (R[n] << 1) | T;",
836     "SET_SR_T (ult);",
837   },
838
839   { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
840     "ult = R[n] & 1;",
841     "R[n] = (UR[n] >> 1) | (T << 31);",
842     "SET_SR_T (ult);",
843   },
844
845   { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
846     "SET_SR_T (R[n] < 0);",
847     "R[n] <<= 1;",
848     "R[n] |= T;",
849   },
850
851   { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
852     "SET_SR_T (R[n] & 1);",
853     "R[n] = UR[n] >> 1;",
854     "R[n] |= (T << 31);",
855   },
856
857   { "", "", "rte", "0000000000101011", 
858 #if 0
859     /* SH-[12] */
860     "int tmp = PC;",
861     "SET_NIP (PT2H (RLAT (R[15]) + 2));",
862     "R[15] += 4;",
863     "SET_SR (RLAT (R[15]) & 0x3f3);",
864     "R[15] += 4;",
865     "Delay_Slot (PC + 2);",
866 #else
867     "SET_SR (SSR);",
868     "SET_NIP (PT2H (SPC));",
869     "cycles += 2;",
870     "Delay_Slot (PC + 2);",
871 #endif
872   },
873
874   { "", "", "rts", "0000000000001011",
875     "SET_NIP (PT2H (PR));",
876     "cycles += 2;",
877     "Delay_Slot (PC + 2);",
878   },
879
880   /* sh-dsp */
881   { "", "n", "setrc <REG_N>", "0100nnnn00010100",
882     "SET_RC (R[n]);",
883   },
884   { "", "n", "setrc #<imm>", "10000010i8*1....",
885     /* It would be more realistic to let loop_start point to some static
886        memory that contains an illegal opcode and then give a bus error when
887        the loop is eventually encountered, but it seems not only simpler,
888        but also more debugging-friendly to just catch the failure here.  */
889     "if (BUSERROR (RS | RE, maskw))",
890     "  RAISE_EXCEPTION (SIGILL);",
891     "else {",
892     "  SET_RC (i);",
893     "  loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
894     "  CHECK_INSN_PTR (insn_ptr);",
895     "}",
896   },
897
898   { "", "", "sets", "0000000001011000",
899     "SET_SR_S (1);",
900   },
901
902   { "", "", "sett", "0000000000011000",
903     "SET_SR_T (1);",
904   },
905
906   { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
907     "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
908   },
909
910   { "n", "n", "shal <REG_N>", "0100nnnn00100000",
911     "SET_SR_T (R[n] < 0);",
912     "R[n] <<= 1;",
913   },
914
915   { "n", "n", "shar <REG_N>", "0100nnnn00100001",
916     "SET_SR_T (R[n] & 1);",
917     "R[n] = R[n] >> 1;",
918   },
919
920   { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
921     "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
922   },
923
924   { "n", "n", "shll <REG_N>", "0100nnnn00000000",
925     "SET_SR_T (R[n] < 0);",
926     "R[n] <<= 1;",
927   },
928
929   { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
930     "R[n] <<= 2;",
931   },
932   { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
933     "R[n] <<= 8;",
934   },
935   { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
936     "R[n] <<= 16;",
937   },
938
939   { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
940     "SET_SR_T (R[n] & 1);",
941     "R[n] = UR[n] >> 1;",
942   },
943
944   { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
945     "R[n] = UR[n] >> 2;",
946   },
947   { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
948     "R[n] = UR[n] >> 8;",
949   },
950   { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
951     "R[n] = UR[n] >> 16;",
952   },
953
954   { "", "", "sleep", "0000000000011011",
955     "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
956   },
957
958   { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
959     "R[n] = CREG (m);",
960   },
961
962 #if 0
963   { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
964     "R[n] = SGR;",
965   },
966   { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
967     "R[n] = DBR;",
968   },
969 #endif
970   { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
971     "MA (1);",
972     "R[n] -= 4;",
973     "WLAT (R[n], CREG (m));",
974   },
975 #if 0
976   { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
977     "MA (1);",
978     "R[n] -= 4;",
979     "WLAT (R[n], SGR);",
980   },
981   { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
982     "MA (1);",
983     "R[n] -= 4;",
984     "WLAT (R[n], DBR);",
985   },
986 #endif
987
988   { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
989     "R[n] = SREG (m);",
990   },
991   { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
992     "MA (1);",
993     "R[n] -= 4;",
994     "WLAT (R[n], SREG (m));",
995   },
996
997   { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
998     "R[n] -= R[m];",
999   },
1000
1001   { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1002     "ult = R[n] - T;",
1003     "SET_SR_T (ult > R[n]);",
1004     "R[n] = ult - R[m];",
1005     "SET_SR_T (T || (R[n] > ult));",
1006   },
1007
1008   { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1009     "ult = R[n] - R[m];",
1010     "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1011     "R[n] = ult;",
1012   },
1013
1014   { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1015     "R[n] = ((R[m] & 0xffff0000)",
1016     "        | ((R[m] << 8) & 0xff00)",
1017     "        | ((R[m] >> 8) & 0x00ff));",
1018   },
1019   { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1020     "R[n] = (((R[m] << 16) & 0xffff0000)",
1021     "        | ((R[m] >> 16) & 0x00ffff));",
1022   },
1023
1024   { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1025     "MA (1);",
1026     "ult = RBAT(R[n]);",
1027     "SET_SR_T (ult == 0);",
1028     "WBAT(R[n],ult|0x80);",
1029   },
1030
1031   { "0", "", "trapa #<imm>", "11000011i8*1....", 
1032     "long imm = 0xff & i;",
1033     "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1034     "  nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1035 #if 0
1036     "else {",
1037     /* SH-[12] */
1038     "  R[15]-=4;",
1039     "  WLAT (R[15], GET_SR());",
1040     "  R[15]-=4;",
1041     "  WLAT (R[15], PH2T (PC + 2));",
1042 #else
1043     "else if (!SR_BL) {",
1044     "  SSR = GET_SR();",
1045     "  SPC = PH2T (PC + 2);",
1046     "  SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1047     "  /* FIXME: EXPEVT = 0x00000160; */",
1048 #endif
1049     "  SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1050     "}",
1051   },
1052
1053   { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1054     "SET_SR_T ((R[n] & R[m]) == 0);",
1055   },
1056   { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1057     "SET_SR_T ((R0 & i) == 0);",
1058   },
1059   { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1060     "MA (1);",
1061     "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1062   },
1063
1064   { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1065     "R0 ^= i;",
1066   },
1067   { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1068     "R[n] ^= R[m];",
1069   },
1070   { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1071     "MA (1);",
1072     "ult = RBAT (GBR+R0);",
1073     "ult ^= i;",
1074     "WBAT (GBR + R0, ult);",
1075   },
1076
1077   { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1078     "R[n] = (((R[n] >> 16) & 0xffff)",
1079     "        | ((R[m] << 16) & 0xffff0000));",
1080   },
1081
1082 #if 0
1083   { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1084     "divl(0,R[n],R[m]);",
1085   },
1086   { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1087     "divl(0,R[n],R[m]);",
1088   },
1089 #endif
1090
1091   {0, 0}};
1092
1093 op movsxy_tab[] =
1094 {
1095 /* If this is disabled, the simulator speeds up by about 12% on a
1096    450 MHz PIII - 9% with ACE_FAST.
1097    Maybe we should have separate simulator loops?  */
1098 #if 1
1099   { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1100     "MA (1);",
1101     "R[n] -= 2;",
1102     "DSP_R (m) = RSWAT (R[n]) << 16;",
1103     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1104   },
1105   { "", "n",  "movs.w @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0100",
1106     "MA (1);",
1107     "DSP_R (m) = RSWAT (R[n]) << 16;",
1108     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1109   },
1110   { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1111     "MA (1);",
1112     "DSP_R (m) = RSWAT (R[n]) << 16;",
1113     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1114     "R[n] += 2;",
1115   },
1116   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1117     "MA (1);",
1118     "DSP_R (m) = RSWAT (R[n]) << 16;",
1119     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1120     "R[n] += R[8];",
1121   },
1122   { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1123     "MA (1);",
1124     "R[n] -= 2;",
1125     "DSP_R (m) = RSWAT (R[n]);",
1126   },
1127   { "", "n",  "movs.w @<REG_N>,<DSP_GRD_M>",  "111101NNGGGG0100",
1128     "MA (1);",
1129     "DSP_R (m) = RSWAT (R[n]);",
1130   },
1131   { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1132     "MA (1);",
1133     "DSP_R (m) = RSWAT (R[n]);",
1134     "R[n] += 2;",
1135   },
1136   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1137     "MA (1);",
1138     "DSP_R (m) = RSWAT (R[n]);",
1139     "R[n] += R[8];",
1140   },
1141   { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1142     "MA (1);",
1143     "R[n] -= 2;",
1144     "WWAT (R[n], DSP_R (m) >> 16);",
1145   },
1146   { "", "n",  "movs.w <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0101",
1147     "MA (1);",
1148     "WWAT (R[n], DSP_R (m) >> 16);",
1149   },
1150   { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1151     "MA (1);",
1152     "WWAT (R[n], DSP_R (m) >> 16);",
1153     "R[n] += 2;",
1154   },
1155   { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1156     "MA (1);",
1157     "WWAT (R[n], DSP_R (m) >> 16);",
1158     "R[n] += R[8];",
1159   },
1160   { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1161     "MA (1);",
1162     "R[n] -= 2;",
1163     "WWAT (R[n], SEXT (DSP_R (m)));",
1164   },
1165   { "", "n",  "movs.w <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0101",
1166     "MA (1);",
1167     "WWAT (R[n], SEXT (DSP_R (m)));",
1168   },
1169   { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1170     "MA (1);",
1171     "WWAT (R[n], SEXT (DSP_R (m)));",
1172     "R[n] += 2;",
1173   },
1174   { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1175     "MA (1);",
1176     "WWAT (R[n], SEXT (DSP_R (m)));",
1177     "R[n] += R[8];",
1178   },
1179   { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1180     "MA (1);",
1181     "R[n] -= 4;",
1182     "DSP_R (m) = RLAT (R[n]);",
1183     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1184   },
1185   { "", "n",  "movs.l @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0110",
1186     "MA (1);",
1187     "DSP_R (m) = RLAT (R[n]);",
1188     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1189   },
1190   { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1191     "MA (1);",
1192     "DSP_R (m) = RLAT (R[n]);",
1193     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1194     "R[n] += 4;",
1195   },
1196   { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1197     "MA (1);",
1198     "DSP_R (m) = RLAT (R[n]);",
1199     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1200     "R[n] += R[8];",
1201   },
1202   { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1203     "MA (1);",
1204     "R[n] -= 4;",
1205     "WLAT (R[n], DSP_R (m));",
1206   },
1207   { "", "n",  "movs.l <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0111",
1208     "MA (1);",
1209     "WLAT (R[n], DSP_R (m));",
1210   },
1211   { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1212     "MA (1);",
1213     "WLAT (R[n], DSP_R (m));",
1214     "R[n] += 4;",
1215   },
1216   { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1217     "MA (1);",
1218     "WLAT (R[n], DSP_R (m));",
1219     "R[n] += R[8];",
1220   },
1221   { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1222     "MA (1);",
1223     "R[n] -= 4;",
1224     "WLAT (R[n], SEXT (DSP_R (m)));",
1225   },
1226   { "", "n",  "movs.l <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0111",
1227     "MA (1);",
1228     "WLAT (R[n], SEXT (DSP_R (m)));",
1229   },
1230   { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1231     "MA (1);",
1232     "WLAT (R[n], SEXT (DSP_R (m)));",
1233     "R[n] += 4;",
1234   },
1235   { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1236     "MA (1);",
1237     "WLAT (R[n], SEXT (DSP_R (m)));",
1238     "R[n] += R[8];",
1239   },
1240   { "", "n", "movx.w @<REG_x>,<DSP_XX>",   "111100xxXX000100",
1241     "DSP_R (m) = RSWAT (R[n]) << 16;",
1242     "iword &= 0xfd53; goto top;",
1243   },
1244   { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1245     "DSP_R (m) = RSWAT (R[n]) << 16;",
1246     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1247     "iword &= 0xfd53; goto top;",
1248   },
1249   { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1250     "DSP_R (m) = RSWAT (R[n]) << 16;",
1251     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1252     "iword &= 0xfd53; goto top;",
1253   },
1254   { "", "n", "movx.w <DSP_Aa>,@<REG_x>",   "111100xxaa100100",
1255     "WWAT (R[n], DSP_R (m) >> 16);",
1256     "iword &= 0xfd53; goto top;",
1257   },
1258   { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1259     "WWAT (R[n], DSP_R (m) >> 16);",
1260     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1261     "iword &= 0xfd53; goto top;",
1262   },
1263   { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
1264     "WWAT (R[n], DSP_R (m) >> 16);",
1265     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1266     "iword &= 0xfd53; goto top;",
1267   },
1268   { "", "n", "movy.w @<REG_y>,<DSP_YY>",   "111100yyYY000001",
1269     "DSP_R (m) = RSWAT (R[n]) << 16;",
1270   },
1271   { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
1272     "DSP_R (m) = RSWAT (R[n]) << 16;",
1273     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1274   },
1275   { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000010",
1276     "DSP_R (m) = RSWAT (R[n]) << 16;",
1277     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1278   },
1279   { "", "n", "movy.w <DSP_Aa>,@<REG_y>",   "111100yyAA010001",
1280     "WWAT (R[n], DSP_R (m) >> 16);",
1281   },
1282   { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
1283     "WWAT (R[n], DSP_R (m) >> 16);",
1284     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1285   },
1286   { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010010",
1287     "WWAT (R[n], DSP_R (m) >> 16);",
1288     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1289   },
1290   { "", "", "nopx nopy", "1111000000000000",
1291     "/* nop */",
1292   },
1293   { "", "", "ppi", "1111100000000000",
1294     "ppi_insn (RIAT (nip));",
1295     "nip += 2;",
1296     "iword &= 0xf7ff; goto top;",
1297   },
1298 #endif
1299   {0, 0}};
1300
1301 op ppi_tab[] =
1302 {
1303   { "","", "pshl #<imm>,dz",    "00000iiim16.zzzz",
1304     "int Sz = DSP_R (z) & 0xffff0000;",
1305     "",
1306     "if (i < 16)",
1307     "  res = Sz << i;",
1308     "else if (i >= 128 - 16)",
1309     "  res = Sz >> 128 - i;",
1310     "else",
1311     "  {",
1312     "    RAISE_EXCEPTION (SIGILL);",
1313     "    return;",
1314     "  }",
1315     "res &= 0xffff0000;",
1316     "res_grd = 0;",
1317     "goto logical;",
1318   },
1319   { "","", "psha #<imm>,dz",    "00010iiim32.zzzz",
1320     "int Sz = DSP_R (z);",
1321     "int Sz_grd = GET_DSP_GRD (z);",
1322     "",
1323     "if (i < 32)",
1324     "  {",
1325     "    if (i == 32)",
1326     "      {",
1327     "        res = 0;",
1328     "        res_grd = Sz;",
1329     "      }",
1330     "    else",
1331     "      {",
1332     "        res = Sz << i;",
1333     "        res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1334     "      }",
1335     "    res_grd = SEXT (res_grd);",
1336     "    carry = res_grd & 1;",
1337     "  }",
1338     "else if (i >= 96)",
1339     "  {",
1340     "    i = 128 - i;",
1341     "    if (i == 32)",
1342     "      {",
1343     "        res_grd = SIGN32 (Sz_grd);",
1344     "        res = Sz_grd;",
1345     "      }",
1346     "    else",
1347     "      {",
1348     "        res = Sz >> i | Sz_grd << 32 - i;",
1349     "        res_grd = Sz_grd >> i;",
1350     "      }",
1351     "    carry = Sz >> (i - 1) & 1;",
1352     "  }",
1353     "else",
1354     "  {",
1355     "    RAISE_EXCEPTION (SIGILL);",
1356     "    return;",
1357     "  }",
1358     "COMPUTE_OVERFLOW;",
1359     "greater_equal = 0;",
1360   },
1361   { "","", "pmuls Se,Sf,Dg",    "0100eeffxxyygguu",
1362     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1363     "if (res == 0x80000000)",
1364     "  res = 0x7fffffff;",
1365     "DSP_R (g) = res;",
1366     "DSP_GRD (g) = SIGN32 (res);",
1367     "return;",
1368   },
1369   { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg",      "0110eeffxxyygguu",
1370     "int Sx = DSP_R (x);",
1371     "int Sx_grd = GET_DSP_GRD (x);",
1372     "int Sy = DSP_R (y);",
1373     "int Sy_grd = SIGN32 (Sy);",
1374     "",
1375     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1376     "if (res == 0x80000000)",
1377     "  res = 0x7fffffff;",
1378     "DSP_R (g) = res;",
1379     "DSP_GRD (g) = SIGN32 (res);",
1380     "",
1381     "z = u;",
1382     "res = Sx - Sy;",
1383     "carry = (unsigned) res > (unsigned) Sx;",
1384     "res_grd = Sx_grd - Sy_grd - carry;",
1385     "COMPUTE_OVERFLOW;",
1386     "ADD_SUB_GE;",
1387   },
1388   { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg",      "0111eeffxxyygguu",
1389     "int Sx = DSP_R (x);",
1390     "int Sx_grd = GET_DSP_GRD (x);",
1391     "int Sy = DSP_R (y);",
1392     "int Sy_grd = SIGN32 (Sy);",
1393     "",
1394     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1395     "if (res == 0x80000000)",
1396     "  res = 0x7fffffff;",
1397     "DSP_R (g) = res;",
1398     "DSP_GRD (g) = SIGN32 (res);",
1399     "",
1400     "z = u;",
1401     "res = Sx + Sy;",
1402     "carry = (unsigned) res < (unsigned) Sx;",
1403     "res_grd = Sx_grd + Sy_grd + carry;",
1404     "COMPUTE_OVERFLOW;",
1405   },
1406   { "","", "psubc Sx,Sy,Dz",            "10100000xxyyzzzz",
1407     "int Sx = DSP_R (x);",
1408     "int Sx_grd = GET_DSP_GRD (x);",
1409     "int Sy = DSP_R (y);",
1410     "int Sy_grd = SIGN32 (Sy);",
1411     "",
1412     "res = Sx - Sy - (DSR & 1);",
1413     "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1414     "res_grd = Sx_grd + Sy_grd + carry;",
1415     "COMPUTE_OVERFLOW;",
1416     "ADD_SUB_GE;",
1417     "DSR &= ~0xf1;\n",
1418     "if (res || res_grd)\n",
1419     "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1420     "else\n",
1421     "  DSR |= DSR_MASK_Z | overflow;\n",
1422     "DSR |= carry;\n",
1423     "goto assign_z;\n",
1424   },
1425   { "","", "paddc Sx,Sy,Dz",    "10110000xxyyzzzz",
1426     "int Sx = DSP_R (x);",
1427     "int Sx_grd = GET_DSP_GRD (x);",
1428     "int Sy = DSP_R (y);",
1429     "int Sy_grd = SIGN32 (Sy);",
1430     "",
1431     "res = Sx + Sy + (DSR & 1);",
1432     "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1433     "res_grd = Sx_grd + Sy_grd + carry;",
1434     "COMPUTE_OVERFLOW;",
1435     "ADD_SUB_GE;",
1436     "DSR &= ~0xf1;\n",
1437     "if (res || res_grd)\n",
1438     "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1439     "else\n",
1440     "  DSR |= DSR_MASK_Z | overflow;\n",
1441     "DSR |= carry;\n",
1442     "goto assign_z;\n",
1443   },
1444   { "","", "pcmp Sx,Sy",        "10000100xxyy....",
1445     "int Sx = DSP_R (x);",
1446     "int Sx_grd = GET_DSP_GRD (x);",
1447     "int Sy = DSP_R (y);",
1448     "int Sy_grd = SIGN32 (Sy);",
1449     "",
1450     "z = 17; /* Ignore result.  */",
1451     "res = Sx - Sy;",
1452     "carry = (unsigned) res > (unsigned) Sx;",
1453     "res_grd = Sx_grd - Sy_grd - carry;",
1454     "COMPUTE_OVERFLOW;",
1455     "ADD_SUB_GE;",
1456   },
1457   { "","", "pwsb Sx,Sy,Dz",     "10100100xxyyzzzz",
1458   },
1459   { "","", "pwad Sx,Sy,Dz",     "10110100xxyyzzzz",
1460   },
1461   { "","", "pabs Sx,Dz",        "10001000xx..zzzz",
1462     "res = DSP_R (x);",
1463     "res_grd = GET_DSP_GRD (x);",
1464     "if (res >= 0)",
1465     "  carry = 0;",
1466     "else",
1467     "  {",
1468     "    res = -res;",
1469     "    carry = (res != 0); /* The manual has a bug here.  */", 
1470     "    res_grd = -res_grd - carry;", 
1471     "  }",
1472     "COMPUTE_OVERFLOW;",
1473     "/* ??? The re-computing of overflow after",
1474     "   saturation processing is specific to pabs.  */",
1475     "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1476     "ADD_SUB_GE;",
1477   },
1478   { "","", "prnd Sx,Dz",        "10011000xx..zzzz",
1479     "int Sx = DSP_R (x);",
1480     "int Sx_grd = GET_DSP_GRD (x);",
1481     "",
1482     "res = Sx + 0x8000;",
1483     "carry = (unsigned) res < (unsigned) Sx;",
1484     "res_grd = Sx_grd + carry;",
1485     "COMPUTE_OVERFLOW;",
1486     "ADD_SUB_GE;",
1487   },
1488   { "","", "pabs Sy,Dz",        "10101000..yyzzzz",
1489     "res = DSP_R (y);",
1490     "res_grd = 0;",
1491     "overflow = 0;",
1492     "greater_equal = DSR_MASK_G;",
1493     "if (res >= 0)",
1494     "  carry = 0;",
1495     "else",
1496     "  {",
1497     "    res = -res;",
1498     "    carry = 1;",
1499     "    if (res < 0)",
1500     "      {",
1501     "        if (S)",
1502     "          res = 0x7fffffff;",
1503     "        else",
1504     "          {",
1505     "            overflow = DSR_MASK_V;",
1506     "            greater_equal = 0;",
1507     "          }",
1508     "      }",
1509     "  }",
1510   },
1511   { "","", "prnd Sy,Dz",        "10111000..yyzzzz",
1512     "int Sy = DSP_R (y);",
1513     "int Sy_grd = SIGN32 (Sy);",
1514     "",
1515     "res = Sy + 0x8000;",
1516     "carry = (unsigned) res < (unsigned) Sy;",
1517     "res_grd = Sy_grd + carry;",
1518     "COMPUTE_OVERFLOW;",
1519     "ADD_SUB_GE;",
1520   },
1521   { "","", "(if cc) pshl Sx,Sy,Dz",     "100000ccxxyyzzzz",
1522     "int Sx = DSP_R (x) & 0xffff0000;",
1523     "int Sy = DSP_R (y) >> 16 & 0x7f;",
1524     "",
1525     "if (Sy < 16)",
1526     "  res = Sx << Sy;",
1527     "else if (Sy >= 128 - 16)",
1528     "  res = Sx >> 128 - Sy;",
1529     "else",
1530     "  {",
1531     "    RAISE_EXCEPTION (SIGILL);",
1532     "    return;",
1533     "  }",
1534     "goto cond_logical;",
1535   },
1536   { "","", "(if cc) psha Sx,Sy,Dz",     "100100ccxxyyzzzz",
1537     "int Sx = DSP_R (x);",
1538     "int Sx_grd = GET_DSP_GRD (x);",
1539     "int Sy = DSP_R (y) >> 16 & 0x7f;",
1540     "",
1541     "if (Sy < 32)",
1542     "  {",
1543     "    if (Sy == 32)",
1544     "      {",
1545     "        res = 0;",
1546     "        res_grd = Sx;",
1547     "      }",
1548     "    else",
1549     "      {",
1550     "        res = Sx << Sy;",
1551     "        res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1552     "      }",
1553     "    res_grd = SEXT (res_grd);",
1554     "    carry = res_grd & 1;",
1555     "  }",
1556     "else if (Sy >= 96)",
1557     "  {",
1558     "    Sy = 128 - Sy;",
1559     "    if (Sy == 32)",
1560     "      {",
1561     "        res_grd = SIGN32 (Sx_grd);",
1562     "        res = Sx_grd;",
1563     "      }",
1564     "    else",
1565     "      {",
1566     "        res = Sx >> Sy | Sx_grd << 32 - Sy;",
1567     "        res_grd = Sx_grd >> Sy;",
1568     "      }",
1569     "    carry = Sx >> (Sy - 1) & 1;",
1570     "  }",
1571     "else",
1572     "  {",
1573     "    RAISE_EXCEPTION (SIGILL);",
1574     "    return;",
1575     "  }",
1576     "COMPUTE_OVERFLOW;",
1577     "greater_equal = 0;",
1578   },
1579   { "","", "(if cc) psub Sx,Sy,Dz",     "101000ccxxyyzzzz",
1580     "int Sx = DSP_R (x);",
1581     "int Sx_grd = GET_DSP_GRD (x);",
1582     "int Sy = DSP_R (y);",
1583     "int Sy_grd = SIGN32 (Sy);",
1584     "",
1585     "res = Sx - Sy;",
1586     "carry = (unsigned) res > (unsigned) Sx;",
1587     "res_grd = Sx_grd - Sy_grd - carry;",
1588     "COMPUTE_OVERFLOW;",
1589     "ADD_SUB_GE;",
1590   },
1591   { "","", "(if cc) padd Sx,Sy,Dz",     "101100ccxxyyzzzz",
1592     "int Sx = DSP_R (x);",
1593     "int Sx_grd = GET_DSP_GRD (x);",
1594     "int Sy = DSP_R (y);",
1595     "int Sy_grd = SIGN32 (Sy);",
1596     "",
1597     "res = Sx + Sy;",
1598     "carry = (unsigned) res < (unsigned) Sx;",
1599     "res_grd = Sx_grd + Sy_grd + carry;",
1600     "COMPUTE_OVERFLOW;",
1601     "ADD_SUB_GE;",
1602   },
1603   { "","", "(if cc) pand Sx,Sy,Dz",     "100101ccxxyyzzzz",
1604     "res = DSP_R (x) & DSP_R (y);",
1605   "cond_logical:",
1606     "res &= 0xffff0000;",
1607     "res_grd = 0;",
1608     "if (iword & 0x200)\n",
1609     "  goto assign_z;\n",
1610   "logical:",
1611     "carry = 0;",
1612     "overflow = 0;",
1613     "greater_equal = 0;",
1614     "DSR &= ~0xf1;\n",
1615     "if (res)\n",
1616     "  DSR |= res >> 26 & DSR_MASK_N;\n",
1617     "else\n",
1618     "  DSR |= DSR_MASK_Z;\n",
1619     "goto assign_dc;\n",
1620   },
1621   { "","", "(if cc) pxor Sx,Sy,Dz",     "101001ccxxyyzzzz",
1622     "res = DSP_R (x) ^ DSP_R (y);",
1623     "goto cond_logical;",
1624   },
1625   { "","", "(if cc) por Sx,Sy,Dz",      "101101ccxxyyzzzz",
1626     "res = DSP_R (x) | DSP_R (y);",
1627     "goto cond_logical;",
1628   },
1629   { "","", "(if cc) pdec Sx,Dz",        "100010ccxx..zzzz",
1630     "int Sx = DSP_R (x);",
1631     "int Sx_grd = GET_DSP_GRD (x);",
1632     "",
1633     "res = Sx - 0x10000;",
1634     "carry = res > Sx;",
1635     "res_grd = Sx_grd - carry;",
1636     "COMPUTE_OVERFLOW;",
1637     "ADD_SUB_GE;",
1638     "res &= 0xffff0000;",
1639   },
1640   { "","", "(if cc) pinc Sx,Dz",        "100110ccxx..zzzz",
1641     "int Sx = DSP_R (x);",
1642     "int Sx_grd = GET_DSP_GRD (x);",
1643     "",
1644     "res = Sx + 0x10000;",
1645     "carry = res < Sx;",
1646     "res_grd = Sx_grd + carry;",
1647     "COMPUTE_OVERFLOW;",
1648     "ADD_SUB_GE;",
1649     "res &= 0xffff0000;",
1650   },
1651   { "","", "(if cc) pdec Sy,Dz",        "101010cc..yyzzzz",
1652     "int Sy = DSP_R (y);",
1653     "int Sy_grd = SIGN32 (Sy);",
1654     "",
1655     "res = Sy - 0x10000;",
1656     "carry = res > Sy;",
1657     "res_grd = Sy_grd - carry;",
1658     "COMPUTE_OVERFLOW;",
1659     "ADD_SUB_GE;",
1660     "res &= 0xffff0000;",
1661   },
1662   { "","", "(if cc) pinc Sy,Dz",        "101110cc..yyzzzz",
1663     "int Sy = DSP_R (y);",
1664     "int Sy_grd = SIGN32 (Sy);",
1665     "",
1666     "res = Sy + 0x10000;",
1667     "carry = res < Sy;",
1668     "res_grd = Sy_grd + carry;",
1669     "COMPUTE_OVERFLOW;",
1670     "ADD_SUB_GE;",
1671     "res &= 0xffff0000;",
1672   },
1673   { "","", "(if cc) pclr Dz",           "100011cc....zzzz",
1674     "res = 0;",
1675     "res_grd = 0;",
1676     "carry = 0;",
1677     "overflow = 0;",
1678     "greater_equal = 1;",
1679   },
1680   { "","", "(if cc) pdmsb Sx,Dz",       "100111ccxx..zzzz",
1681     "unsigned Sx = DSP_R (x);",
1682     "int Sx_grd = GET_DSP_GRD (x);",
1683     "int i = 16;",
1684     "",
1685     "if (Sx_grd < 0)",
1686     "  {",
1687     "    Sx_grd = ~Sx_grd;",
1688     "    Sx = ~Sx;",
1689     "  }",
1690     "if (Sx_grd)",
1691     "  {",
1692     "    Sx = Sx_grd;",
1693     "    res = -2;",
1694     "  }",
1695     "else if (Sx)",
1696     "  res = 30;",
1697     "else",
1698     "  res = 31;",
1699     "do",
1700     "  {",
1701     "    if (Sx & ~0 << i)",
1702     "      {",
1703     "        res -= i;",
1704     "        Sx >>= i;",
1705     "      }",
1706     "  }",
1707     "while (i >>= 1);",
1708     "res <<= 16;",
1709     "res_grd = SIGN32 (res);",
1710     "carry = 0;",
1711     "overflow = 0;",
1712     "ADD_SUB_GE;",
1713   },
1714   { "","", "(if cc) pdmsb Sy,Dz",       "101111cc..yyzzzz",
1715     "unsigned Sy = DSP_R (y);",
1716     "int i;",
1717     "",
1718     "if (Sy < 0)",
1719     "  Sy = ~Sy;",
1720     "Sy <<= 1;",
1721     "res = 31;",
1722     "do",
1723     "  {",
1724     "    if (Sy & ~0 << i)",
1725     "      {",
1726     "        res -= i;",
1727     "        Sy >>= i;",
1728     "      }",
1729     "  }",
1730     "while (i >>= 1);",
1731     "res <<= 16;",
1732     "res_grd = SIGN32 (res);",
1733     "carry = 0;",
1734     "overflow = 0;",
1735     "ADD_SUB_GE;",
1736   },
1737   { "","", "(if cc) pneg Sx,Dz",        "110010ccxx..zzzz",
1738     "int Sx = DSP_R (x);",
1739     "int Sx_grd = GET_DSP_GRD (x);",
1740     "",
1741     "res = 0 - Sx;",
1742     "carry = res != 0;",
1743     "res_grd = 0 - Sx_grd - carry;",
1744     "COMPUTE_OVERFLOW;",
1745     "ADD_SUB_GE;",
1746   },
1747   { "","", "(if cc) pcopy Sx,Dz",       "110110ccxx..zzzz",
1748     "res = DSP_R (x);",
1749     "res_grd = GET_DSP_GRD (x);",
1750     "carry = 0;",
1751     "COMPUTE_OVERFLOW;",
1752     "ADD_SUB_GE;",
1753   },
1754   { "","", "(if cc) pneg Sy,Dz",        "111010cc..yyzzzz",
1755     "int Sy = DSP_R (y);",
1756     "int Sy_grd = SIGN32 (Sy);",
1757     "",
1758     "res = 0 - Sy;",
1759     "carry = res != 0;",
1760     "res_grd = 0 - Sy_grd - carry;",
1761     "COMPUTE_OVERFLOW;",
1762     "ADD_SUB_GE;",
1763   },
1764   { "","", "(if cc) pcopy Sy,Dz",       "111110cc..yyzzzz",
1765     "res = DSP_R (y);",
1766     "res_grd = SIGN32 (res);",
1767     "carry = 0;",
1768     "COMPUTE_OVERFLOW;",
1769     "ADD_SUB_GE;",
1770   },
1771   { "","", "(if cc) psts MACH,Dz",      "110011cc....zzzz",
1772     "res = MACH;",
1773     "res_grd = SIGN32 (res);",
1774     "goto assign_z;",
1775   },
1776   { "","", "(if cc) psts MACL,Dz",      "110111cc....zzzz",
1777     "res = MACL;",
1778     "res_grd = SIGN32 (res);",
1779     "goto assign_z;",
1780   },
1781   { "","", "(if cc) plds Dz,MACH",      "111011cc....zzzz",
1782     "if (0xa05f >> z & 1)",
1783     "  RAISE_EXCEPTION (SIGILL);",
1784     "else",
1785     "  MACH = DSP_R (z);",
1786     "return;",
1787   },
1788   { "","", "(if cc) plds Dz,MACL",      "111111cc....zzzz",
1789     "if (0xa05f >> z & 1)",
1790     "  RAISE_EXCEPTION (SIGILL);",
1791     "else",
1792     "  MACL = DSP_R (z) = res;",
1793     "return;",
1794   },
1795   {0, 0}
1796 };
1797
1798 /* Tables of things to put into enums for sh-opc.h */
1799 static char *nibble_type_list[] =
1800 {
1801   "HEX_0",
1802   "HEX_1",
1803   "HEX_2",
1804   "HEX_3",
1805   "HEX_4",
1806   "HEX_5",
1807   "HEX_6",
1808   "HEX_7",
1809   "HEX_8",
1810   "HEX_9",
1811   "HEX_A",
1812   "HEX_B",
1813   "HEX_C",
1814   "HEX_D",
1815   "HEX_E",
1816   "HEX_F",
1817   "REG_N",
1818   "REG_M",
1819   "BRANCH_12",
1820   "BRANCH_8",
1821   "DISP_8",
1822   "DISP_4",
1823   "IMM_4",
1824   "IMM_4BY2",
1825   "IMM_4BY4",
1826   "PCRELIMM_8BY2",
1827   "PCRELIMM_8BY4",
1828   "IMM_8",
1829   "IMM_8BY2",
1830   "IMM_8BY4",
1831   0
1832 };
1833 static
1834 char *arg_type_list[] =
1835 {
1836   "A_END",
1837   "A_BDISP12",
1838   "A_BDISP8",
1839   "A_DEC_M",
1840   "A_DEC_N",
1841   "A_DISP_GBR",
1842   "A_DISP_PC",
1843   "A_DISP_REG_M",
1844   "A_DISP_REG_N",
1845   "A_GBR",
1846   "A_IMM",
1847   "A_INC_M",
1848   "A_INC_N",
1849   "A_IND_M",
1850   "A_IND_N",
1851   "A_IND_R0_REG_M",
1852   "A_IND_R0_REG_N",
1853   "A_MACH",
1854   "A_MACL",
1855   "A_PR",
1856   "A_R0",
1857   "A_R0_GBR",
1858   "A_REG_M",
1859   "A_REG_N",
1860   "A_SR",
1861   "A_VBR",
1862   "A_SSR",
1863   "A_SPC",
1864   0,
1865 };
1866
1867 static void
1868 make_enum_list (name, s)
1869      char *name;
1870      char **s;
1871 {
1872   int i = 1;
1873   printf ("typedef enum {\n");
1874   while (*s)
1875     {
1876       printf ("\t%s,\n", *s);
1877       s++;
1878       i++;
1879     }
1880   printf ("} %s;\n", name);
1881 }
1882
1883 static int
1884 qfunc (a, b)
1885      op *a;
1886      op *b;
1887 {
1888   char bufa[9];
1889   char bufb[9];
1890   int diff;
1891
1892   memcpy (bufa, a->code, 4);
1893   memcpy (bufa + 4, a->code + 12, 4);
1894   bufa[8] = 0;
1895
1896   memcpy (bufb, b->code, 4);
1897   memcpy (bufb + 4, b->code + 12, 4);
1898   bufb[8] = 0;
1899   diff = strcmp (bufa, bufb);
1900   /* Stabilize the sort, so that later entries can override more general
1901      preceding entries.  */
1902   return diff ? diff : a - b;
1903 }
1904
1905 static void
1906 sorttab ()
1907 {
1908   op *p = tab;
1909   int len = 0;
1910
1911   while (p->name)
1912     {
1913       p++;
1914       len++;
1915     }
1916   qsort (tab, len, sizeof (*p), qfunc);
1917 }
1918
1919 static void
1920 gengastab ()
1921 {
1922   op *p;
1923   sorttab ();
1924   for (p = tab; p->name; p++)
1925     {
1926       printf ("%s %-30s\n", p->code, p->name);
1927     }
1928
1929
1930 }
1931
1932 /* Convert a string of 4 binary digits into an int */
1933
1934 static
1935 int
1936 bton (s)
1937      char *s;
1938
1939 {
1940   int n = 0;
1941   int v = 8;
1942   while (v)
1943     {
1944       if (*s == '1')
1945         n |= v;
1946       v >>= 1;
1947       s++;
1948     }
1949   return n;
1950 }
1951
1952 static unsigned char table[1 << 16];
1953
1954 /* Take an opcode expand all varying fields in it out and fill all the
1955   right entries in 'table' with the opcode index*/
1956
1957 static void
1958 expand_opcode (shift, val, i, s)
1959      int shift;
1960      int val;
1961      int i;
1962      char *s;
1963 {
1964   int j;
1965
1966   if (*s == 0)
1967     {
1968       table[val] = i;
1969     }
1970   else
1971     {
1972       switch (s[0])
1973         {
1974
1975         case '0':
1976         case '1':
1977           {
1978             int m, mv;
1979
1980             val |= bton (s) << shift;
1981             if (s[2] == '0' || s[2] == '1')
1982               expand_opcode (shift - 4, val, i, s + 4);
1983             else if (s[2] == 'N')
1984               for (j = 0; j < 4; j++)
1985                 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1986             else if (s[2] == 'x')
1987               for (j = 0; j < 4; j += 2)
1988                 for (m = 0; m < 32; m++)
1989                   {
1990                     /* Ignore illegal nopy */
1991                     if ((m & 7) == 0 && m != 0)
1992                       continue;
1993                     mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
1994                     expand_opcode (shift - 4, val | mv | (j << shift), i,
1995                                    s + 4);
1996                   }
1997             else if (s[2] == 'y')
1998               for (j = 0; j < 2; j++)
1999                 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2000             break;
2001           }
2002         case 'n':
2003         case 'm':
2004           for (j = 0; j < 16; j++)
2005             {
2006               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2007
2008             }
2009           break;
2010         case 'M':
2011           /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2012           for (j = 5; j < 16; j++)
2013             if (j != 6)
2014               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2015           break;
2016         case 'G':
2017           /* A1G, A0G: */
2018           for (j = 13; j <= 15; j +=2)
2019             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2020           break;
2021         case 's':
2022           /* System registers mach, macl, pr: */
2023           for (j = 0; j < 3; j++)
2024             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2025           /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2026           for (j = 5; j < 12; j++)
2027             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2028           break;
2029         case 'X':
2030         case 'a':
2031           val |= bton (s) << shift;
2032           for (j = 0; j < 16; j += 8)
2033             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2034           break;
2035         case 'Y':
2036         case 'A':
2037           val |= bton (s) << shift;
2038           for (j = 0; j < 8; j += 4)
2039             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2040           break;
2041
2042         default:
2043           for (j = 0; j < (1 << (shift + 4)); j++)
2044             {
2045               table[val | j] = i;
2046             }
2047         }
2048     }
2049 }
2050
2051 /* Print the jump table used to index an opcode into a switch
2052    statement entry. */
2053
2054 static void
2055 dumptable (name, size, start)
2056      char *name;
2057      int size;
2058      int start;
2059 {
2060   int lump = 256;
2061   int online = 16;
2062
2063   int i = start;
2064
2065   printf ("unsigned char %s[%d]={\n", name, size);
2066   while (i < start + size)
2067     {
2068       int j = 0;
2069
2070       printf ("/* 0x%x */\n", i);
2071
2072       while (j < lump)
2073         {
2074           int k = 0;
2075           while (k < online)
2076             {
2077               printf ("%2d", table[i + j + k]);
2078               if (j + k < lump)
2079                 printf (",");
2080
2081               k++;
2082             }
2083           j += k;
2084           printf ("\n");
2085         }
2086       i += j;
2087     }
2088   printf ("};\n");
2089 }
2090
2091
2092 static void
2093 filltable (p)
2094      op *p;
2095 {
2096   static int index = 1;
2097
2098   sorttab ();
2099   for (; p->name; p++)
2100     {
2101       p->index = index++;
2102       expand_opcode (12, 0, p->index, p->code);
2103     }
2104 }
2105
2106 /* Table already contais all the switch case tags for 16-bit opcode double
2107    data transfer (ddt) insns, and the switch case tag for processing parallel
2108    processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
2109    latter tag to represent all combinations of ppi with ddt.  */
2110 static void
2111 ppi_moves ()
2112 {
2113   int i;
2114
2115   for (i = 0xf000; i < 0xf400; i++)
2116     if (table[i])
2117       table[i + 0x800] = table[0xf800];
2118 }
2119
2120 static void
2121 gensim_caselist (p)
2122      op *p;
2123 {
2124   for (; p->name; p++)
2125     {
2126       int j;
2127       int sextbit = -1;
2128       int needm = 0;
2129       int needn = 0;
2130       
2131       char *s = p->code;
2132
2133       printf ("  /* %s %s */\n", p->name, p->code);
2134       printf ("  case %d:      \n", p->index);
2135
2136       printf ("    {\n");
2137       while (*s)
2138         {
2139           switch (*s)
2140             {
2141             case '0':
2142             case '1':
2143               s += 2;
2144               break;
2145             case '.':
2146               s += 4;
2147               break;
2148             case 'n':
2149               printf ("      int n = (iword >>8) & 0xf;\n");
2150               needn = 1;
2151               s += 4;
2152               break;
2153             case 'N':
2154               printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2155               s += 2;
2156               break;
2157             case 'x':
2158               printf ("      int n = ((iword >> 9) & 1) + 4;\n");
2159               needn = 1;
2160               s += 2;
2161               break;
2162             case 'y':
2163               printf ("      int n = ((iword >> 8) & 1) + 6;\n");
2164               needn = 1;
2165               s += 2;
2166               break;
2167             case 'm':
2168               needm = 1;
2169             case 's':
2170             case 'M':
2171             case 'G':
2172               printf ("      int m = (iword >>4) & 0xf;\n");
2173               s += 4;
2174               break;
2175             case 'X':
2176               printf ("      int m = ((iword >> 7) & 1) + 8;\n");
2177               s += 2;
2178               break;
2179             case 'a':
2180               printf ("      int m = 7 - ((iword >> 6) & 2);\n");
2181               s += 2;
2182               break;
2183             case 'Y':
2184               printf ("      int m = ((iword >> 6) & 1) + 10;\n");
2185               s += 2;
2186               break;
2187             case 'A':
2188               printf ("      int m = 7 - ((iword >> 5) & 2);\n");
2189               s += 2;
2190               break;
2191
2192             case 'i':
2193               printf ("      int i = (iword & 0x");
2194
2195               switch (s[1])
2196                 {
2197                 case '4':
2198                   printf ("f");
2199                   break;
2200                 case '8':
2201                   printf ("ff");
2202                   break;
2203                 case '1':
2204                   sextbit = 12;
2205
2206                   printf ("fff");
2207                   break;
2208                 }
2209               printf (")");
2210
2211               switch (s[3])
2212                 {
2213                 case '1':
2214                   break;
2215                 case '2':
2216                   printf ("<<1");
2217                   break;
2218                 case '4':
2219                   printf ("<<2");
2220                   break;
2221                 }
2222               printf (";\n");
2223               s += 4;
2224             }
2225         }
2226       if (sextbit > 0)
2227         {
2228           printf ("      i = (i ^ (1<<%d))-(1<<%d);\n",
2229                   sextbit - 1, sextbit - 1);
2230         }
2231
2232       if (needm && needn)
2233         printf ("      TB(m,n);\n");  
2234       else if (needm)
2235         printf ("      TL(m);\n");
2236       else if (needn)
2237         printf ("      TL(n);\n");
2238
2239       {
2240         /* Do the refs */
2241         char *r;
2242         for (r = p->refs; *r; r++)
2243           {
2244             if (*r == '0') printf("      CREF(0);\n"); 
2245             if (*r == '8') printf("      CREF(8);\n"); 
2246             if (*r == '9') printf("      CREF(9);\n"); 
2247             if (*r == 'n') printf("      CREF(n);\n"); 
2248             if (*r == 'm') printf("      CREF(m);\n"); 
2249           }
2250       }
2251
2252       printf ("      {\n");
2253       for (j = 0; j < MAX_NR_STUFF; j++)
2254         {
2255           if (p->stuff[j])
2256             {
2257               printf ("        %s\n", p->stuff[j]);
2258             }
2259         }
2260       printf ("      }\n");
2261
2262       {
2263         /* Do the defs */
2264         char *r;
2265         for (r = p->defs; *r; r++) 
2266           {
2267             if (*r == '0') printf("      CDEF(0);\n"); 
2268             if (*r == 'n') printf("      CDEF(n);\n"); 
2269             if (*r == 'm') printf("      CDEF(m);\n"); 
2270           }
2271       }
2272
2273       printf ("      break;\n");
2274       printf ("    }\n");
2275     }
2276 }
2277
2278 static void
2279 gensim ()
2280 {
2281   printf ("{\n");
2282   printf ("  switch (jump_table[iword]) {\n");
2283
2284   gensim_caselist (tab);
2285   gensim_caselist (movsxy_tab);
2286
2287   printf ("  default:\n");
2288   printf ("    {\n");
2289   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2290   printf ("    }\n");
2291   printf ("  }\n");
2292   printf ("}\n");
2293 }
2294
2295 static void
2296 gendefines ()
2297 {
2298   op *p;
2299   filltable (tab);
2300   for (p = tab; p->name; p++)
2301     {
2302       char *s = p->name;
2303       printf ("#define OPC_");
2304       while (*s) {
2305         if (isupper(*s)) 
2306           *s = tolower(*s);
2307         if (isalpha(*s)) printf("%c", *s);
2308         if (*s == ' ') printf("_");
2309         if (*s == '@') printf("ind_");
2310         if (*s == ',') printf("_");
2311         s++;
2312       }
2313       printf(" %d\n",p->index);
2314     }
2315 }
2316
2317 static int ppi_index;
2318
2319 /* Take an ppi code, expand all varying fields in it and fill all the
2320    right entries in 'table' with the opcode index.  */
2321
2322 static void
2323 expand_ppi_code (val, i, s)
2324      int val;
2325      int i;
2326      char *s;
2327 {
2328   int j;
2329
2330   for (;;)
2331     {
2332       switch (s[0])
2333         {
2334         /* The last eight bits are disregarded for the switch table.  */
2335         case 'm':
2336         case 'x':
2337         case '.':
2338           table[val] = i;
2339           return;
2340         case '0':
2341           val += val;
2342           s++;
2343           break;
2344         case '1':
2345           val += val + 1;
2346           s++;
2347           break;
2348         case 'i':
2349         case 'e': case 'f':
2350           val += val;
2351           s++;
2352           expand_ppi_code (val, i, s);
2353           val++;
2354           break;
2355         case 'c':
2356           val <<= 2;
2357           s += 2;
2358           val++;
2359           expand_ppi_code (val, ppi_index++, s);
2360           val++;
2361           expand_ppi_code (val, i, s);
2362           val++;
2363           break;
2364         }
2365     }
2366 }
2367
2368 static void
2369 ppi_filltable ()
2370 {
2371   op *p;
2372   ppi_index = 1;
2373
2374   for (p = ppi_tab; p->name; p++)
2375     {
2376       p->index = ppi_index++;
2377       expand_ppi_code (0, p->index, p->code);
2378     }
2379 }
2380
2381 static void
2382 ppi_gensim ()
2383 {
2384   op *p = ppi_tab;
2385
2386   printf ("#define DSR_MASK_G 0x80\n");
2387   printf ("#define DSR_MASK_Z 0x40\n");
2388   printf ("#define DSR_MASK_N 0x20\n");
2389   printf ("#define DSR_MASK_V 0x10\n");
2390   printf ("\n");
2391   printf ("#define COMPUTE_OVERFLOW do {\\\n");
2392   printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2393   printf ("  if (overflow && S) \\\n");
2394   printf ("    { \\\n");
2395   printf ("      if (res_grd & 0x80) \\\n");
2396   printf ("        { \\\n");
2397   printf ("          res = 0x80000000; \\\n");
2398   printf ("          res_grd |=  0xff; \\\n");
2399   printf ("        } \\\n");
2400   printf ("      else \\\n");
2401   printf ("        { \\\n");
2402   printf ("          res = 0x7fffffff; \\\n");
2403   printf ("          res_grd &= ~0xff; \\\n");
2404   printf ("        } \\\n");
2405   printf ("      overflow = 0; \\\n");
2406   printf ("    } \\\n");
2407   printf ("} while (0)\n");
2408   printf ("\n");
2409   printf ("#define ADD_SUB_GE \\\n");
2410   printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2411   printf ("\n");
2412   printf ("static void\n");
2413   printf ("ppi_insn (iword)\n");
2414   printf ("     int iword;\n");
2415   printf ("{\n");
2416   printf ("  static char e_tab[] = { 8,  9, 10,  5};\n");
2417   printf ("  static char f_tab[] = {10, 11,  8,  5};\n");
2418   printf ("  static char x_tab[] = { 8,  9,  7,  5};\n");
2419   printf ("  static char y_tab[] = {10, 11, 12, 14};\n");
2420   printf ("  static char g_tab[] = {12, 14,  7,  5};\n");
2421   printf ("  static char u_tab[] = { 8, 10,  7,  5};\n");
2422   printf ("\n");
2423   printf ("  int z;\n");
2424   printf ("  int res, res_grd;\n");
2425   printf ("  int carry, overflow, greater_equal;\n");
2426   printf ("\n");
2427   printf ("  switch (ppi_table[iword >> 8]) {\n");
2428
2429   for (; p->name; p++)
2430     {
2431       int shift, j;
2432       int cond = 0;
2433       int havedecl = 0;
2434       
2435       char *s = p->code;
2436
2437       printf ("  /* %s %s */\n", p->name, p->code);
2438       printf ("  case %d:      \n", p->index);
2439
2440       printf ("    {\n");
2441       for (shift = 16; *s; )
2442         {
2443           switch (*s)
2444             {
2445             case 'i':
2446               printf ("      int i = (iword >> 4) & 0x7f;\n");
2447               s += 6;
2448               break;
2449             case 'e':
2450             case 'f':
2451             case 'x':
2452             case 'y':
2453             case 'g':
2454             case 'u':
2455               shift -= 2;
2456               printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
2457                       *s, *s, shift);
2458               havedecl = 1;
2459               s += 2;
2460               break;
2461             case 'c':
2462               printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2463               printf ("\tbreak;\n");
2464               printf ("    }\n");
2465               printf ("  case %d:      \n", p->index + 1);
2466               printf ("    {\n");
2467               cond = 1;
2468             case '0':
2469             case '1':
2470             case '.':
2471               shift -= 2;
2472               s += 2;
2473               break;
2474             case 'z':
2475               if (havedecl)
2476                 printf ("\n");
2477               printf ("      z = iword & 0xf;\n");
2478               havedecl = 2;
2479               s += 4;
2480               break;
2481             }
2482         }
2483       if (havedecl == 1)
2484         printf ("\n");
2485       else if (havedecl == 2)
2486         printf ("      {\n");
2487       for (j = 0; j < MAX_NR_STUFF; j++)
2488         {
2489           if (p->stuff[j])
2490             {
2491               printf ("      %s%s\n",
2492                       (havedecl == 2 ? "  " : ""),
2493                       p->stuff[j]);
2494             }
2495         }
2496       if (havedecl == 2)
2497         printf ("      }\n");
2498       if (cond)
2499         {
2500           printf ("      if (iword & 0x200)\n");
2501           printf ("        goto assign_z;\n");
2502         }
2503       printf ("      break;\n");
2504       printf ("    }\n");
2505     }
2506
2507   printf ("  default:\n");
2508   printf ("    {\n");
2509   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2510   printf ("      return;\n");
2511   printf ("    }\n");
2512   printf ("  }\n");
2513   printf ("  DSR &= ~0xf1;\n");
2514   printf ("  if (res || res_grd)\n");
2515   printf ("    DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2516   printf ("  else\n");
2517   printf ("    DSR |= DSR_MASK_Z | overflow;\n");
2518   printf (" assign_dc:\n");
2519   printf ("  switch (DSR >> 1 & 7)\n");
2520   printf ("    {\n");
2521   printf ("    case 0: /* Carry Mode */\n");
2522   printf ("      DSR |= carry;\n");
2523   printf ("    case 1: /* Negative Value Mode */\n");
2524   printf ("      DSR |= res_grd >> 7 & 1;\n");
2525   printf ("    case 2: /* Zero Value Mode */\n");
2526   printf ("      DSR |= DSR >> 6 & 1;\n");
2527   printf ("    case 3: /* Overflow mode\n");
2528   printf ("      DSR |= overflow >> 4;\n");
2529   printf ("    case 4: /* Signed Greater Than Mode */\n");
2530   printf ("      DSR |= DSR >> 7 & 1;\n");
2531   printf ("    case 4: /* Signed Greater Than Or Equal Mode */\n");
2532   printf ("      DSR |= greater_equal >> 7;\n");
2533   printf ("    }\n");
2534   printf (" assign_z:\n");
2535   printf ("  if (0xa05f >> z & 1)\n");
2536   printf ("    {\n");
2537   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2538   printf ("      return;\n");
2539   printf ("    }\n");
2540   printf ("  DSP_R (z) = res;\n");
2541   printf ("  DSP_GRD (z) = res_grd;\n");
2542   printf ("}\n");
2543 }
2544
2545 int
2546 main (ac, av)
2547      int ac;
2548      char **av;
2549 {
2550   /* verify the table before anything else */
2551   {
2552     op *p;
2553     for (p = tab; p->name; p++)
2554       {
2555         /* check that the code field contains 16 bits */
2556         if (strlen (p->code) != 16)
2557           {
2558             fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2559                      p->code, strlen (p->code), p->name);
2560             abort ();
2561           }
2562       }
2563   }
2564
2565   /* now generate the requested data */
2566   if (ac > 1)
2567     {
2568       if (strcmp (av[1], "-t") == 0)
2569         {
2570           gengastab ();
2571         }
2572       else if (strcmp (av[1], "-d") == 0)
2573         {
2574           gendefines ();
2575         }
2576       else if (strcmp (av[1], "-s") == 0)
2577         {
2578           filltable (tab);
2579           dumptable ("sh_jump_table", 1 << 16, 0);
2580
2581           memset (table, 0, sizeof table);
2582           filltable (movsxy_tab);
2583           ppi_moves ();
2584           dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2585
2586           memset (table, 0, sizeof table);
2587           ppi_filltable ();
2588           dumptable ("ppi_table", 1 << 8, 0);
2589         }
2590       else if (strcmp (av[1], "-x") == 0)
2591         {
2592           filltable (tab);
2593           filltable (movsxy_tab);
2594           gensim ();
2595         }
2596       else if (strcmp (av[1], "-p") == 0)
2597         {
2598           ppi_filltable ();
2599           ppi_gensim ();
2600         }
2601     }
2602   else
2603     fprintf (stderr, "Opcode table generation no longer supported.\n");
2604   return 0;
2605 }