This commit was manufactured by cvs2svn to create branch
[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      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   /* sh3e */
230   { "", "", "fabs <FREG_N>", "1111nnnn01011101",
231     "FP_UNARY (n, fabs);",
232     "/* FIXME: FR(n) &= 0x7fffffff; */",
233   },
234
235   /* sh3e */
236   { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
237     "FP_OP (n, +, m);",
238   },
239
240   /* sh3e */
241   { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
242     "FP_CMP (n, ==, m);",
243   },
244   /* sh3e */
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   /* sh3e */
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   /* sh3e */
295   { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
296     "SET_FR (n, (float)0.0);",
297     "/* FIXME: check for DP and (n & 1) == 0? */",
298   },
299
300   /* sh3e */
301   { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
302     "SET_FR (n, (float)1.0);",
303     "/* FIXME: check for DP and (n & 1) == 0? */",
304   },
305
306   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
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   /* sh3e */
434   { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
435     "FP_OP(n, *, m);",
436   },
437
438   /* sh3e */
439   { "", "", "fneg <FREG_N>", "1111nnnn01001101",
440     "FP_UNARY(n, -);",
441   },
442
443   /* 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   /* sh3e */
459   { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
460     "FP_OP(n, -, m);",
461   },
462
463   /* sh3e */
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   /* sh3e */
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   /* sh3e / sh-dsp (lds <REG_N>,DSR) */
565   { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
566     "SET_FPSCR(R[n]);",
567   },
568   /* sh3e / 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   { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
754     "/* FIXME: Not implemented */",
755     "RAISE_EXCEPTION (SIGILL);",
756   },
757
758   { "n", "", "movt <REG_N>", "0000nnnn00101001",
759     "R[n] = T;",
760   },
761
762   { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
763     "MACL = ((int)R[n]) * ((int)R[m]);",
764   },
765 #if 0
766   { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
767     "MACL = R[n] * R[m];",
768   },
769 #endif
770
771   /* muls.w - see muls */
772   { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
773     "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
774   },
775
776   /* mulu.w - see mulu */
777   { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
778     "MACL = (((unsigned int)(unsigned short)R[n])",
779     "        * ((unsigned int)(unsigned short)R[m]));",
780   },
781
782   { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
783     "R[n] = - R[m];",
784   },
785
786   { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
787     "ult = -T;",
788     "SET_SR_T (ult > 0);",
789     "R[n] = ult - R[m];",
790     "SET_SR_T (T || (R[n] > ult));",
791   },
792
793   { "", "", "nop", "0000000000001001",
794     "/* nop */",
795   },
796
797   { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
798     "R[n] = ~R[m];",
799   },
800
801   { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
802     "/* FIXME: Not implemented */",
803     "RAISE_EXCEPTION (SIGILL);",
804   },
805
806   { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
807     "/* FIXME: Not implemented */",
808     "RAISE_EXCEPTION (SIGILL);",
809   },
810
811   { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
812     "RSBAT (R[n]); /* Take exceptions like byte load.  */",
813     "/* FIXME: Cache not implemented */",
814   },
815
816   { "0", "", "or #<imm>,R0", "11001011i8*1....",
817     "R0 |= i;",
818   },
819   { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
820     "R[n] |= R[m];",
821   },
822   { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
823     "MA (1);",
824     "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
825   },
826
827   { "", "n", "pref @<REG_N>", "0000nnnn10000011",
828     "/* Except for the effect on the cache - which is not simulated -",
829     "   this is like a nop.  */",
830   },
831
832   { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
833     "ult = R[n] < 0;",
834     "R[n] = (R[n] << 1) | T;",
835     "SET_SR_T (ult);",
836   },
837
838   { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
839     "ult = R[n] & 1;",
840     "R[n] = (UR[n] >> 1) | (T << 31);",
841     "SET_SR_T (ult);",
842   },
843
844   { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
845     "SET_SR_T (R[n] < 0);",
846     "R[n] <<= 1;",
847     "R[n] |= T;",
848   },
849
850   { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
851     "SET_SR_T (R[n] & 1);",
852     "R[n] = UR[n] >> 1;",
853     "R[n] |= (T << 31);",
854   },
855
856   { "", "", "rte", "0000000000101011", 
857 #if 0
858     /* SH-[12] */
859     "int tmp = PC;",
860     "SET_NIP (PT2H (RLAT (R[15]) + 2));",
861     "R[15] += 4;",
862     "SET_SR (RLAT (R[15]) & 0x3f3);",
863     "R[15] += 4;",
864     "Delay_Slot (PC + 2);",
865 #else
866     "SET_SR (SSR);",
867     "SET_NIP (PT2H (SPC));",
868     "cycles += 2;",
869     "Delay_Slot (PC + 2);",
870 #endif
871   },
872
873   { "", "", "rts", "0000000000001011",
874     "SET_NIP (PT2H (PR));",
875     "cycles += 2;",
876     "Delay_Slot (PC + 2);",
877   },
878
879   /* sh-dsp */
880   { "", "n", "setrc <REG_N>", "0100nnnn00010100",
881     "SET_RC (R[n]);",
882   },
883   { "", "n", "setrc #<imm>", "10000010i8*1....",
884     /* It would be more realistic to let loop_start point to some static
885        memory that contains an illegal opcode and then give a bus error when
886        the loop is eventually encountered, but it seems not only simpler,
887        but also more debugging-friendly to just catch the failure here.  */
888     "if (BUSERROR (RS | RE, maskw))",
889     "  RAISE_EXCEPTION (SIGILL);",
890     "else {",
891     "  SET_RC (i);",
892     "  loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
893     "  CHECK_INSN_PTR (insn_ptr);",
894     "}",
895   },
896
897   { "", "", "sets", "0000000001011000",
898     "SET_SR_S (1);",
899   },
900
901   { "", "", "sett", "0000000000011000",
902     "SET_SR_T (1);",
903   },
904
905   { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
906     "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
907   },
908
909   { "n", "n", "shal <REG_N>", "0100nnnn00100000",
910     "SET_SR_T (R[n] < 0);",
911     "R[n] <<= 1;",
912   },
913
914   { "n", "n", "shar <REG_N>", "0100nnnn00100001",
915     "SET_SR_T (R[n] & 1);",
916     "R[n] = R[n] >> 1;",
917   },
918
919   { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
920     "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
921   },
922
923   { "n", "n", "shll <REG_N>", "0100nnnn00000000",
924     "SET_SR_T (R[n] < 0);",
925     "R[n] <<= 1;",
926   },
927
928   { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
929     "R[n] <<= 2;",
930   },
931   { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
932     "R[n] <<= 8;",
933   },
934   { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
935     "R[n] <<= 16;",
936   },
937
938   { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
939     "SET_SR_T (R[n] & 1);",
940     "R[n] = UR[n] >> 1;",
941   },
942
943   { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
944     "R[n] = UR[n] >> 2;",
945   },
946   { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
947     "R[n] = UR[n] >> 8;",
948   },
949   { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
950     "R[n] = UR[n] >> 16;",
951   },
952
953   { "", "", "sleep", "0000000000011011",
954     "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
955   },
956
957   { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
958     "R[n] = CREG (m);",
959   },
960
961 #if 0
962   { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
963     "R[n] = SGR;",
964   },
965   { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
966     "R[n] = DBR;",
967   },
968 #endif
969   { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
970     "MA (1);",
971     "R[n] -= 4;",
972     "WLAT (R[n], CREG (m));",
973   },
974 #if 0
975   { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
976     "MA (1);",
977     "R[n] -= 4;",
978     "WLAT (R[n], SGR);",
979   },
980   { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
981     "MA (1);",
982     "R[n] -= 4;",
983     "WLAT (R[n], DBR);",
984   },
985 #endif
986
987   { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
988     "R[n] = SREG (m);",
989   },
990   { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
991     "MA (1);",
992     "R[n] -= 4;",
993     "WLAT (R[n], SREG (m));",
994   },
995
996   { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
997     "R[n] -= R[m];",
998   },
999
1000   { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1001     "ult = R[n] - T;",
1002     "SET_SR_T (ult > R[n]);",
1003     "R[n] = ult - R[m];",
1004     "SET_SR_T (T || (R[n] > ult));",
1005   },
1006
1007   { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1008     "ult = R[n] - R[m];",
1009     "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1010     "R[n] = ult;",
1011   },
1012
1013   { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1014     "R[n] = ((R[m] & 0xffff0000)",
1015     "        | ((R[m] << 8) & 0xff00)",
1016     "        | ((R[m] >> 8) & 0x00ff));",
1017   },
1018   { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1019     "R[n] = (((R[m] << 16) & 0xffff0000)",
1020     "        | ((R[m] >> 16) & 0x00ffff));",
1021   },
1022
1023   { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1024     "MA (1);",
1025     "ult = RBAT(R[n]);",
1026     "SET_SR_T (ult == 0);",
1027     "WBAT(R[n],ult|0x80);",
1028   },
1029
1030   { "0", "", "trapa #<imm>", "11000011i8*1....", 
1031     "long imm = 0xff & i;",
1032     "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1033     "  nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1034 #if 0
1035     "else {",
1036     /* SH-[12] */
1037     "  R[15]-=4;",
1038     "  WLAT (R[15], GET_SR());",
1039     "  R[15]-=4;",
1040     "  WLAT (R[15], PH2T (PC + 2));",
1041 #else
1042     "else if (!SR_BL) {",
1043     "  SSR = GET_SR();",
1044     "  SPC = PH2T (PC + 2);",
1045     "  SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1046     "  /* FIXME: EXPEVT = 0x00000160; */",
1047 #endif
1048     "  SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1049     "}",
1050   },
1051
1052   { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1053     "SET_SR_T ((R[n] & R[m]) == 0);",
1054   },
1055   { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1056     "SET_SR_T ((R0 & i) == 0);",
1057   },
1058   { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1059     "MA (1);",
1060     "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1061   },
1062
1063   { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1064     "R0 ^= i;",
1065   },
1066   { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1067     "R[n] ^= R[m];",
1068   },
1069   { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1070     "MA (1);",
1071     "ult = RBAT (GBR+R0);",
1072     "ult ^= i;",
1073     "WBAT (GBR + R0, ult);",
1074   },
1075
1076   { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1077     "R[n] = (((R[n] >> 16) & 0xffff)",
1078     "        | ((R[m] << 16) & 0xffff0000));",
1079   },
1080
1081 #if 0
1082   { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1083     "divl(0,R[n],R[m]);",
1084   },
1085   { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1086     "divl(0,R[n],R[m]);",
1087   },
1088 #endif
1089
1090   {0, 0}};
1091
1092 op movsxy_tab[] =
1093 {
1094 /* If this is disabled, the simulator speeds up by about 12% on a
1095    450 MHz PIII - 9% with ACE_FAST.
1096    Maybe we should have separate simulator loops?  */
1097 #if 1
1098   { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1099     "MA (1);",
1100     "R[n] -= 2;",
1101     "DSP_R (m) = RSWAT (R[n]) << 16;",
1102     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1103   },
1104   { "", "n",  "movs.w @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0100",
1105     "MA (1);",
1106     "DSP_R (m) = RSWAT (R[n]) << 16;",
1107     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1108   },
1109   { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1110     "MA (1);",
1111     "DSP_R (m) = RSWAT (R[n]) << 16;",
1112     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1113     "R[n] += 2;",
1114   },
1115   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1116     "MA (1);",
1117     "DSP_R (m) = RSWAT (R[n]) << 16;",
1118     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1119     "R[n] += R[8];",
1120   },
1121   { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1122     "MA (1);",
1123     "R[n] -= 2;",
1124     "DSP_R (m) = RSWAT (R[n]);",
1125   },
1126   { "", "n",  "movs.w @<REG_N>,<DSP_GRD_M>",  "111101NNGGGG0100",
1127     "MA (1);",
1128     "DSP_R (m) = RSWAT (R[n]);",
1129   },
1130   { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1131     "MA (1);",
1132     "DSP_R (m) = RSWAT (R[n]);",
1133     "R[n] += 2;",
1134   },
1135   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1136     "MA (1);",
1137     "DSP_R (m) = RSWAT (R[n]);",
1138     "R[n] += R[8];",
1139   },
1140   { "n", "n", "<DSP_REG_M>,movs.w @-<REG_N>", "111101NNMMMM0001",
1141     "MA (1);",
1142     "R[n] -= 2;",
1143     "WWAT (R[n], DSP_R (m) >> 16);",
1144   },
1145   { "", "n",  "movs.w <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0101",
1146     "MA (1);",
1147     "WWAT (R[n], DSP_R (m) >> 16);",
1148   },
1149   { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1150     "MA (1);",
1151     "WWAT (R[n], DSP_R (m) >> 16);",
1152     "R[n] += 2;",
1153   },
1154   { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1155     "MA (1);",
1156     "WWAT (R[n], DSP_R (m) >> 16);",
1157     "R[n] += R[8];",
1158   },
1159   { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1160     "MA (1);",
1161     "R[n] -= 2;",
1162     "WWAT (R[n], SEXT (DSP_R (m)));",
1163   },
1164   { "", "n",  "movs.w <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0101",
1165     "MA (1);",
1166     "WWAT (R[n], SEXT (DSP_R (m)));",
1167   },
1168   { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1169     "MA (1);",
1170     "WWAT (R[n], SEXT (DSP_R (m)));",
1171     "R[n] += 2;",
1172   },
1173   { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1174     "MA (1);",
1175     "WWAT (R[n], SEXT (DSP_R (m)));",
1176     "R[n] += R[8];",
1177   },
1178   { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1179     "MA (1);",
1180     "R[n] -= 4;",
1181     "DSP_R (m) = RLAT (R[n]);",
1182     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1183   },
1184   { "", "n",  "movs.l @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0110",
1185     "MA (1);",
1186     "DSP_R (m) = RLAT (R[n]);",
1187     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1188   },
1189   { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1190     "MA (1);",
1191     "DSP_R (m) = RLAT (R[n]);",
1192     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1193     "R[n] += 4;",
1194   },
1195   { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1196     "MA (1);",
1197     "DSP_R (m) = RLAT (R[n]);",
1198     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1199     "R[n] += R[8];",
1200   },
1201   { "n", "n", "<DSP_REG_M>,movs.l @-<REG_N>", "111101NNMMMM0011",
1202     "MA (1);",
1203     "R[n] -= 4;",
1204     "WLAT (R[n], DSP_R (m));",
1205   },
1206   { "", "n",  "movs.l <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0111",
1207     "MA (1);",
1208     "WLAT (R[n], DSP_R (m));",
1209   },
1210   { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1211     "MA (1);",
1212     "WLAT (R[n], DSP_R (m));",
1213     "R[n] += 4;",
1214   },
1215   { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1216     "MA (1);",
1217     "WLAT (R[n], DSP_R (m));",
1218     "R[n] += R[8];",
1219   },
1220   { "n", "n", "<DSP_GRD_M>,movs.l @-<REG_N>", "111101NNGGGG0011",
1221     "MA (1);",
1222     "R[n] -= 4;",
1223     "WLAT (R[n], SEXT (DSP_R (m)));",
1224   },
1225   { "", "n",  "movs.l <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0111",
1226     "MA (1);",
1227     "WLAT (R[n], SEXT (DSP_R (m)));",
1228   },
1229   { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1230     "MA (1);",
1231     "WLAT (R[n], SEXT (DSP_R (m)));",
1232     "R[n] += 4;",
1233   },
1234   { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1235     "MA (1);",
1236     "WLAT (R[n], SEXT (DSP_R (m)));",
1237     "R[n] += R[8];",
1238   },
1239   { "", "n", "movx.w @<REG_x>,<DSP_XX>",   "111100xxXX000100",
1240     "DSP_R (m) = RSWAT (R[n]) << 16;",
1241     "iword &= 0xfd53; goto top;",
1242   },
1243   { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1244     "DSP_R (m) = RSWAT (R[n]) << 16;",
1245     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1246     "iword &= 0xfd53; goto top;",
1247   },
1248   { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1249     "DSP_R (m) = RSWAT (R[n]) << 16;",
1250     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1251     "iword &= 0xfd53; goto top;",
1252   },
1253   { "", "n", "movx.w <DSP_Aa>,@<REG_x>",   "111100xxaa100100",
1254     "WWAT (R[n], DSP_R (m) >> 16);",
1255     "iword &= 0xfd53; goto top;",
1256   },
1257   { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1258     "WWAT (R[n], DSP_R (m) >> 16);",
1259     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1260     "iword &= 0xfd53; goto top;",
1261   },
1262   { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101000",
1263     "WWAT (R[n], DSP_R (m) >> 16);",
1264     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1265     "iword &= 0xfd53; goto top;",
1266   },
1267   { "", "n", "movy.w @<REG_y>,<DSP_YY>",   "111100yyYY000001",
1268     "DSP_R (m) = RSWAT (R[n]) << 16;",
1269   },
1270   { "n", "n", "movy.w @<REG_x>+,<DSP_YY>", "111100yyYY000010",
1271     "DSP_R (m) = RSWAT (R[n]) << 16;",
1272     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1273   },
1274   { "n", "n9","movy.w @<REG_x>+REG_9,<DSP_YY>", "111100yyYY000010",
1275     "DSP_R (m) = RSWAT (R[n]) << 16;",
1276     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1277   },
1278   { "", "n", "movy.w <DSP_Aa>,@<REG_x>",   "111100yyAA010001",
1279     "WWAT (R[n], DSP_R (m) >> 16);",
1280   },
1281   { "n", "n", "movy.w <DSP_Aa>,@<REG_x>+", "111100yyAA010010",
1282     "WWAT (R[n], DSP_R (m) >> 16);",
1283     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1284   },
1285   { "n", "n9", "movy.w <DSP_Aa>,@<REG_x>+REG_9", "111100yyAA010010",
1286     "WWAT (R[n], DSP_R (m) >> 16);",
1287     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1288   },
1289   { "", "", "nopx nopy", "1111000000000000",
1290     "/* nop */",
1291   },
1292   { "", "", "ppi", "1111100000000000",
1293     "ppi_insn (RIAT (nip));",
1294     "nip += 2;",
1295     "iword &= 0xf7ff; goto top;",
1296   },
1297 #endif
1298   {0, 0}};
1299
1300 op ppi_tab[] =
1301 {
1302   { "","", "pshl #<imm>,dz",    "00000iiim16.zzzz",
1303     "int Sz = DSP_R (z) & 0xffff0000;",
1304     "",
1305     "if (i < 16)",
1306     "  res = Sz << i;",
1307     "else if (i >= 128 - 16)",
1308     "  res = Sz >> 128 - i;",
1309     "else",
1310     "  {",
1311     "    RAISE_EXCEPTION (SIGILL);",
1312     "    return;",
1313     "  }",
1314     "res &= 0xffff0000;",
1315     "res_grd = 0;",
1316     "goto logical;",
1317   },
1318   { "","", "psha #<imm>,dz",    "00010iiim32.zzzz",
1319     "int Sz = DSP_R (z);",
1320     "int Sz_grd = GET_DSP_GRD (z);",
1321     "",
1322     "if (i < 32)",
1323     "  {",
1324     "    if (i == 32)",
1325     "      {",
1326     "        res = 0;",
1327     "        res_grd = Sz;",
1328     "      }",
1329     "    else",
1330     "      {",
1331     "        res = Sz << i;",
1332     "        res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1333     "      }",
1334     "    res_grd = SEXT (res_grd);",
1335     "    carry = res_grd & 1;",
1336     "  }",
1337     "else if (i >= 96)",
1338     "  {",
1339     "    i = 128 - i;",
1340     "    if (i == 32)",
1341     "      {",
1342     "        res_grd = SIGN32 (Sz_grd);",
1343     "        res = Sz_grd;",
1344     "      }",
1345     "    else",
1346     "      {",
1347     "        res = Sz >> i | Sz_grd << 32 - i;",
1348     "        res_grd = Sz_grd >> i;",
1349     "      }",
1350     "    carry = Sz >> (i - 1) & 1;",
1351     "  }",
1352     "else",
1353     "  {",
1354     "    RAISE_EXCEPTION (SIGILL);",
1355     "    return;",
1356     "  }",
1357     "COMPUTE_OVERFLOW;",
1358     "greater_equal = 0;",
1359   },
1360   { "","", "pmuls Se,Sf,Dg",    "0100eeffxxyygguu",
1361     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1362     "if (res == 0x80000000)",
1363     "  res = 0x7fffffff;",
1364     "DSP_R (g) = res;",
1365     "DSP_GRD (g) = SIGN32 (res);",
1366     "return;",
1367   },
1368   { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg",      "0110eeffxxyygguu",
1369     "int Sx = DSP_R (x);",
1370     "int Sx_grd = GET_DSP_GRD (x);",
1371     "int Sy = DSP_R (y);",
1372     "int Sy_grd = SIGN32 (Sy);",
1373     "",
1374     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1375     "if (res == 0x80000000)",
1376     "  res = 0x7fffffff;",
1377     "DSP_R (g) = res;",
1378     "DSP_GRD (g) = SIGN32 (res);",
1379     "",
1380     "z = u;",
1381     "res = Sx - Sy;",
1382     "carry = (unsigned) res > (unsigned) Sx;",
1383     "res_grd = Sx_grd - Sy_grd - carry;",
1384     "COMPUTE_OVERFLOW;",
1385     "ADD_SUB_GE;",
1386   },
1387   { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg",      "0111eeffxxyygguu",
1388     "int Sx = DSP_R (x);",
1389     "int Sx_grd = GET_DSP_GRD (x);",
1390     "int Sy = DSP_R (y);",
1391     "int Sy_grd = SIGN32 (Sy);",
1392     "",
1393     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1394     "if (res == 0x80000000)",
1395     "  res = 0x7fffffff;",
1396     "DSP_R (g) = res;",
1397     "DSP_GRD (g) = SIGN32 (res);",
1398     "",
1399     "z = u;",
1400     "res = Sx + Sy;",
1401     "carry = (unsigned) res < (unsigned) Sx;",
1402     "res_grd = Sx_grd + Sy_grd + carry;",
1403     "COMPUTE_OVERFLOW;",
1404   },
1405   { "","", "psubc Sx,Sy,Dz",            "10100000xxyyzzzz",
1406     "int Sx = DSP_R (x);",
1407     "int Sx_grd = GET_DSP_GRD (x);",
1408     "int Sy = DSP_R (y);",
1409     "int Sy_grd = SIGN32 (Sy);",
1410     "",
1411     "res = Sx - Sy - (DSR & 1);",
1412     "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1413     "res_grd = Sx_grd + Sy_grd + carry;",
1414     "COMPUTE_OVERFLOW;",
1415     "ADD_SUB_GE;",
1416     "DSR &= ~0xf1;\n",
1417     "if (res || res_grd)\n",
1418     "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1419     "else\n",
1420     "  DSR |= DSR_MASK_Z | overflow;\n",
1421     "DSR |= carry;\n",
1422     "goto assign_z;\n",
1423   },
1424   { "","", "paddc Sx,Sy,Dz",    "10110000xxyyzzzz",
1425     "int Sx = DSP_R (x);",
1426     "int Sx_grd = GET_DSP_GRD (x);",
1427     "int Sy = DSP_R (y);",
1428     "int Sy_grd = SIGN32 (Sy);",
1429     "",
1430     "res = Sx + Sy + (DSR & 1);",
1431     "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1432     "res_grd = Sx_grd + Sy_grd + carry;",
1433     "COMPUTE_OVERFLOW;",
1434     "ADD_SUB_GE;",
1435     "DSR &= ~0xf1;\n",
1436     "if (res || res_grd)\n",
1437     "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1438     "else\n",
1439     "  DSR |= DSR_MASK_Z | overflow;\n",
1440     "DSR |= carry;\n",
1441     "goto assign_z;\n",
1442   },
1443   { "","", "pcmp Sx,Sy",        "10000100xxyy....",
1444     "int Sx = DSP_R (x);",
1445     "int Sx_grd = GET_DSP_GRD (x);",
1446     "int Sy = DSP_R (y);",
1447     "int Sy_grd = SIGN32 (Sy);",
1448     "",
1449     "z = 17; /* Ignore result.  */",
1450     "res = Sx - Sy;",
1451     "carry = (unsigned) res > (unsigned) Sx;",
1452     "res_grd = Sx_grd - Sy_grd - carry;",
1453     "COMPUTE_OVERFLOW;",
1454     "ADD_SUB_GE;",
1455   },
1456   { "","", "pwsb Sx,Sy,Dz",     "10100100xxyyzzzz",
1457   },
1458   { "","", "pwad Sx,Sy,Dz",     "10110100xxyyzzzz",
1459   },
1460   { "","", "pabs Sx,Dz",        "10001000xx..zzzz",
1461     "res = DSP_R (x);",
1462     "res_grd = GET_DSP_GRD (x);",
1463     "if (res >= 0)",
1464     "  carry = 0;",
1465     "else",
1466     "  {",
1467     "    res = -res;",
1468     "    carry = (res != 0); /* The manual has a bug here.  */", 
1469     "    res_grd = -res_grd - carry;", 
1470     "  }",
1471     "COMPUTE_OVERFLOW;",
1472     "/* ??? The re-computing of overflow after",
1473     "   saturation processing is specific to pabs.  */",
1474     "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1475     "ADD_SUB_GE;",
1476   },
1477   { "","", "prnd Sx,Dz",        "10011000xx..zzzz",
1478     "int Sx = DSP_R (x);",
1479     "int Sx_grd = GET_DSP_GRD (x);",
1480     "",
1481     "res = Sx + 0x8000;",
1482     "carry = (unsigned) res < (unsigned) Sx;",
1483     "res_grd = Sx_grd + carry;",
1484     "COMPUTE_OVERFLOW;",
1485     "ADD_SUB_GE;",
1486   },
1487   { "","", "pabs Sy,Dz",        "10101000..yyzzzz",
1488     "res = DSP_R (y);",
1489     "res_grd = 0;",
1490     "overflow = 0;",
1491     "greater_equal = DSR_MASK_G;",
1492     "if (res >= 0)",
1493     "  carry = 0;",
1494     "else",
1495     "  {",
1496     "    res = -res;",
1497     "    carry = 1;",
1498     "    if (res < 0)",
1499     "      {",
1500     "        if (S)",
1501     "          res = 0x7fffffff;",
1502     "        else",
1503     "          {",
1504     "            overflow = DSR_MASK_V;",
1505     "            greater_equal = 0;",
1506     "          }",
1507     "      }",
1508     "  }",
1509   },
1510   { "","", "prnd Sy,Dz",        "10111000..yyzzzz",
1511     "int Sy = DSP_R (y);",
1512     "int Sy_grd = SIGN32 (Sy);",
1513     "",
1514     "res = Sy + 0x8000;",
1515     "carry = (unsigned) res < (unsigned) Sy;",
1516     "res_grd = Sy_grd + carry;",
1517     "COMPUTE_OVERFLOW;",
1518     "ADD_SUB_GE;",
1519   },
1520   { "","", "(if cc) pshl Sx,Sy,Dz",     "100000ccxxyyzzzz",
1521     "int Sx = DSP_R (x) & 0xffff0000;",
1522     "int Sy = DSP_R (y) >> 16 & 0x7f;",
1523     "",
1524     "if (Sy < 16)",
1525     "  res = Sx << Sy;",
1526     "else if (Sy >= 128 - 16)",
1527     "  res = Sx >> 128 - Sy;",
1528     "else",
1529     "  {",
1530     "    RAISE_EXCEPTION (SIGILL);",
1531     "    return;",
1532     "  }",
1533     "goto cond_logical;",
1534   },
1535   { "","", "(if cc) psha Sx,Sy,Dz",     "100100ccxxyyzzzz",
1536     "int Sx = DSP_R (x);",
1537     "int Sx_grd = GET_DSP_GRD (x);",
1538     "int Sy = DSP_R (y) >> 16 & 0x7f;",
1539     "",
1540     "if (Sy < 32)",
1541     "  {",
1542     "    if (Sy == 32)",
1543     "      {",
1544     "        res = 0;",
1545     "        res_grd = Sx;",
1546     "      }",
1547     "    else",
1548     "      {",
1549     "        res = Sx << Sy;",
1550     "        res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1551     "      }",
1552     "    res_grd = SEXT (res_grd);",
1553     "    carry = res_grd & 1;",
1554     "  }",
1555     "else if (Sy >= 96)",
1556     "  {",
1557     "    Sy = 128 - Sy;",
1558     "    if (Sy == 32)",
1559     "      {",
1560     "        res_grd = SIGN32 (Sx_grd);",
1561     "        res = Sx_grd;",
1562     "      }",
1563     "    else",
1564     "      {",
1565     "        res = Sx >> Sy | Sx_grd << 32 - Sy;",
1566     "        res_grd = Sx_grd >> Sy;",
1567     "      }",
1568     "    carry = Sx >> (Sy - 1) & 1;",
1569     "  }",
1570     "else",
1571     "  {",
1572     "    RAISE_EXCEPTION (SIGILL);",
1573     "    return;",
1574     "  }",
1575     "COMPUTE_OVERFLOW;",
1576     "greater_equal = 0;",
1577   },
1578   { "","", "(if cc) psub Sx,Sy,Dz",     "101000ccxxyyzzzz",
1579     "int Sx = DSP_R (x);",
1580     "int Sx_grd = GET_DSP_GRD (x);",
1581     "int Sy = DSP_R (y);",
1582     "int Sy_grd = SIGN32 (Sy);",
1583     "",
1584     "res = Sx - Sy;",
1585     "carry = (unsigned) res > (unsigned) Sx;",
1586     "res_grd = Sx_grd - Sy_grd - carry;",
1587     "COMPUTE_OVERFLOW;",
1588     "ADD_SUB_GE;",
1589   },
1590   { "","", "(if cc) padd Sx,Sy,Dz",     "101100ccxxyyzzzz",
1591     "int Sx = DSP_R (x);",
1592     "int Sx_grd = GET_DSP_GRD (x);",
1593     "int Sy = DSP_R (y);",
1594     "int Sy_grd = SIGN32 (Sy);",
1595     "",
1596     "res = Sx + Sy;",
1597     "carry = (unsigned) res < (unsigned) Sx;",
1598     "res_grd = Sx_grd + Sy_grd + carry;",
1599     "COMPUTE_OVERFLOW;",
1600     "ADD_SUB_GE;",
1601   },
1602   { "","", "(if cc) pand Sx,Sy,Dz",     "100101ccxxyyzzzz",
1603     "res = DSP_R (x) & DSP_R (y);",
1604   "cond_logical:",
1605     "res &= 0xffff0000;",
1606     "res_grd = 0;",
1607     "if (iword & 0x200)\n",
1608     "  goto assign_z;\n",
1609   "logical:",
1610     "carry = 0;",
1611     "overflow = 0;",
1612     "greater_equal = 0;",
1613     "DSR &= ~0xf1;\n",
1614     "if (res)\n",
1615     "  DSR |= res >> 26 & DSR_MASK_N;\n",
1616     "else\n",
1617     "  DSR |= DSR_MASK_Z;\n",
1618     "goto assign_dc;\n",
1619   },
1620   { "","", "(if cc) pxor Sx,Sy,Dz",     "101001ccxxyyzzzz",
1621     "res = DSP_R (x) ^ DSP_R (y);",
1622     "goto cond_logical;",
1623   },
1624   { "","", "(if cc) por Sx,Sy,Dz",      "101101ccxxyyzzzz",
1625     "res = DSP_R (x) | DSP_R (y);",
1626     "goto cond_logical;",
1627   },
1628   { "","", "(if cc) pdec Sx,Dz",        "100010ccxx..zzzz",
1629     "int Sx = DSP_R (x);",
1630     "int Sx_grd = GET_DSP_GRD (x);",
1631     "",
1632     "res = Sx - 0x10000;",
1633     "carry = res > Sx;",
1634     "res_grd = Sx_grd - carry;",
1635     "COMPUTE_OVERFLOW;",
1636     "ADD_SUB_GE;",
1637     "res &= 0xffff0000;",
1638   },
1639   { "","", "(if cc) pinc Sx,Dz",        "100110ccxx..zzzz",
1640     "int Sx = DSP_R (x);",
1641     "int Sx_grd = GET_DSP_GRD (x);",
1642     "",
1643     "res = Sx + 0x10000;",
1644     "carry = res < Sx;",
1645     "res_grd = Sx_grd + carry;",
1646     "COMPUTE_OVERFLOW;",
1647     "ADD_SUB_GE;",
1648     "res &= 0xffff0000;",
1649   },
1650   { "","", "(if cc) pdec Sy,Dz",        "101010cc..yyzzzz",
1651     "int Sy = DSP_R (y);",
1652     "int Sy_grd = SIGN32 (Sy);",
1653     "",
1654     "res = Sy - 0x10000;",
1655     "carry = res > Sy;",
1656     "res_grd = Sy_grd - carry;",
1657     "COMPUTE_OVERFLOW;",
1658     "ADD_SUB_GE;",
1659     "res &= 0xffff0000;",
1660   },
1661   { "","", "(if cc) pinc Sy,Dz",        "101110cc..yyzzzz",
1662     "int Sy = DSP_R (y);",
1663     "int Sy_grd = SIGN32 (Sy);",
1664     "",
1665     "res = Sy + 0x10000;",
1666     "carry = res < Sy;",
1667     "res_grd = Sy_grd + carry;",
1668     "COMPUTE_OVERFLOW;",
1669     "ADD_SUB_GE;",
1670     "res &= 0xffff0000;",
1671   },
1672   { "","", "(if cc) pclr Dz",           "100011cc....zzzz",
1673     "res = 0;",
1674     "res_grd = 0;",
1675     "carry = 0;",
1676     "overflow = 0;",
1677     "greater_equal = 1;",
1678   },
1679   { "","", "(if cc) pdmsb Sx,Dz",       "100111ccxx..zzzz",
1680     "unsigned Sx = DSP_R (x);",
1681     "int Sx_grd = GET_DSP_GRD (x);",
1682     "int i = 16;",
1683     "",
1684     "if (Sx_grd < 0)",
1685     "  {",
1686     "    Sx_grd = ~Sx_grd;",
1687     "    Sx = ~Sx;",
1688     "  }",
1689     "if (Sx_grd)",
1690     "  {",
1691     "    Sx = Sx_grd;",
1692     "    res = -2;",
1693     "  }",
1694     "else if (Sx)",
1695     "  res = 30;",
1696     "else",
1697     "  res = 31;",
1698     "do",
1699     "  {",
1700     "    if (Sx & ~0 << i)",
1701     "      {",
1702     "        res -= i;",
1703     "        Sx >>= i;",
1704     "      }",
1705     "  }",
1706     "while (i >>= 1);",
1707     "res <<= 16;",
1708     "res_grd = SIGN32 (res);",
1709     "carry = 0;",
1710     "overflow = 0;",
1711     "ADD_SUB_GE;",
1712   },
1713   { "","", "(if cc) pdmsb Sy,Dz",       "101111cc..yyzzzz",
1714     "unsigned Sy = DSP_R (y);",
1715     "int i;",
1716     "",
1717     "if (Sy < 0)",
1718     "  Sy = ~Sy;",
1719     "Sy <<= 1;",
1720     "res = 31;",
1721     "do",
1722     "  {",
1723     "    if (Sy & ~0 << i)",
1724     "      {",
1725     "        res -= i;",
1726     "        Sy >>= i;",
1727     "      }",
1728     "  }",
1729     "while (i >>= 1);",
1730     "res <<= 16;",
1731     "res_grd = SIGN32 (res);",
1732     "carry = 0;",
1733     "overflow = 0;",
1734     "ADD_SUB_GE;",
1735   },
1736   { "","", "(if cc) pneg Sx,Dz",        "110010ccxx..zzzz",
1737     "int Sx = DSP_R (x);",
1738     "int Sx_grd = GET_DSP_GRD (x);",
1739     "",
1740     "res = 0 - Sx;",
1741     "carry = res != 0;",
1742     "res_grd = 0 - Sx_grd - carry;",
1743     "COMPUTE_OVERFLOW;",
1744     "ADD_SUB_GE;",
1745   },
1746   { "","", "(if cc) pcopy Sx,Dz",       "110110ccxx..zzzz",
1747     "res = DSP_R (x);",
1748     "res_grd = GET_DSP_GRD (x);",
1749     "carry = 0;",
1750     "COMPUTE_OVERFLOW;",
1751     "ADD_SUB_GE;",
1752   },
1753   { "","", "(if cc) pneg Sy,Dz",        "111010cc..yyzzzz",
1754     "int Sy = DSP_R (y);",
1755     "int Sy_grd = SIGN32 (Sy);",
1756     "",
1757     "res = 0 - Sy;",
1758     "carry = res != 0;",
1759     "res_grd = 0 - Sy_grd - carry;",
1760     "COMPUTE_OVERFLOW;",
1761     "ADD_SUB_GE;",
1762   },
1763   { "","", "(if cc) pcopy Sy,Dz",       "111110cc..yyzzzz",
1764     "res = DSP_R (y);",
1765     "res_grd = SIGN32 (res);",
1766     "carry = 0;",
1767     "COMPUTE_OVERFLOW;",
1768     "ADD_SUB_GE;",
1769   },
1770   { "","", "(if cc) psts MACH,Dz",      "110011cc....zzzz",
1771     "res = MACH;",
1772     "res_grd = SIGN32 (res);",
1773     "goto assign_z;",
1774   },
1775   { "","", "(if cc) psts MACL,Dz",      "110111cc....zzzz",
1776     "res = MACL;",
1777     "res_grd = SIGN32 (res);",
1778     "goto assign_z;",
1779   },
1780   { "","", "(if cc) plds Dz,MACH",      "111011cc....zzzz",
1781     "if (0xa05f >> z & 1)",
1782     "  RAISE_EXCEPTION (SIGILL);",
1783     "else",
1784     "  MACH = DSP_R (z);",
1785     "return;",
1786   },
1787   { "","", "(if cc) plds Dz,MACL",      "111111cc....zzzz",
1788     "if (0xa05f >> z & 1)",
1789     "  RAISE_EXCEPTION (SIGILL);",
1790     "else",
1791     "  MACL = DSP_R (z) = res;",
1792     "return;",
1793   },
1794   {0, 0}
1795 };
1796
1797 /* Tables of things to put into enums for sh-opc.h */
1798 static char *nibble_type_list[] =
1799 {
1800   "HEX_0",
1801   "HEX_1",
1802   "HEX_2",
1803   "HEX_3",
1804   "HEX_4",
1805   "HEX_5",
1806   "HEX_6",
1807   "HEX_7",
1808   "HEX_8",
1809   "HEX_9",
1810   "HEX_A",
1811   "HEX_B",
1812   "HEX_C",
1813   "HEX_D",
1814   "HEX_E",
1815   "HEX_F",
1816   "REG_N",
1817   "REG_M",
1818   "BRANCH_12",
1819   "BRANCH_8",
1820   "DISP_8",
1821   "DISP_4",
1822   "IMM_4",
1823   "IMM_4BY2",
1824   "IMM_4BY4",
1825   "PCRELIMM_8BY2",
1826   "PCRELIMM_8BY4",
1827   "IMM_8",
1828   "IMM_8BY2",
1829   "IMM_8BY4",
1830   0
1831 };
1832 static
1833 char *arg_type_list[] =
1834 {
1835   "A_END",
1836   "A_BDISP12",
1837   "A_BDISP8",
1838   "A_DEC_M",
1839   "A_DEC_N",
1840   "A_DISP_GBR",
1841   "A_DISP_PC",
1842   "A_DISP_REG_M",
1843   "A_DISP_REG_N",
1844   "A_GBR",
1845   "A_IMM",
1846   "A_INC_M",
1847   "A_INC_N",
1848   "A_IND_M",
1849   "A_IND_N",
1850   "A_IND_R0_REG_M",
1851   "A_IND_R0_REG_N",
1852   "A_MACH",
1853   "A_MACL",
1854   "A_PR",
1855   "A_R0",
1856   "A_R0_GBR",
1857   "A_REG_M",
1858   "A_REG_N",
1859   "A_SR",
1860   "A_VBR",
1861   "A_SSR",
1862   "A_SPC",
1863   0,
1864 };
1865
1866 static void
1867 make_enum_list (name, s)
1868      char *name;
1869      char **s;
1870 {
1871   int i = 1;
1872   printf ("typedef enum {\n");
1873   while (*s)
1874     {
1875       printf ("\t%s,\n", *s);
1876       s++;
1877       i++;
1878     }
1879   printf ("} %s;\n", name);
1880 }
1881
1882 static int
1883 qfunc (a, b)
1884      op *a;
1885      op *b;
1886 {
1887   char bufa[9];
1888   char bufb[9];
1889   int diff;
1890
1891   memcpy (bufa, a->code, 4);
1892   memcpy (bufa + 4, a->code + 12, 4);
1893   bufa[8] = 0;
1894
1895   memcpy (bufb, b->code, 4);
1896   memcpy (bufb + 4, b->code + 12, 4);
1897   bufb[8] = 0;
1898   diff = strcmp (bufa, bufb);
1899   /* Stabilize the sort, so that later entries can override more general
1900      preceding entries.  */
1901   return diff ? diff : a - b;
1902 }
1903
1904 static void
1905 sorttab ()
1906 {
1907   op *p = tab;
1908   int len = 0;
1909
1910   while (p->name)
1911     {
1912       p++;
1913       len++;
1914     }
1915   qsort (tab, len, sizeof (*p), qfunc);
1916 }
1917
1918 static void
1919 gengastab ()
1920 {
1921   op *p;
1922   sorttab ();
1923   for (p = tab; p->name; p++)
1924     {
1925       printf ("%s %-30s\n", p->code, p->name);
1926     }
1927
1928
1929 }
1930
1931 /* Convert a string of 4 binary digits into an int */
1932
1933 static
1934 int
1935 bton (s)
1936      char *s;
1937
1938 {
1939   int n = 0;
1940   int v = 8;
1941   while (v)
1942     {
1943       if (*s == '1')
1944         n |= v;
1945       v >>= 1;
1946       s++;
1947     }
1948   return n;
1949 }
1950
1951 static unsigned char table[1 << 16];
1952
1953 /* Take an opcode expand all varying fields in it out and fill all the
1954   right entries in 'table' with the opcode index*/
1955
1956 static void
1957 expand_opcode (shift, val, i, s)
1958      int shift;
1959      int val;
1960      int i;
1961      char *s;
1962 {
1963   int j;
1964
1965   if (*s == 0)
1966     {
1967       table[val] = i;
1968     }
1969   else
1970     {
1971       switch (s[0])
1972         {
1973
1974         case '0':
1975         case '1':
1976           {
1977             int m, mv;
1978
1979             val |= bton (s) << shift;
1980             if (s[2] == '0' || s[2] == '1')
1981               expand_opcode (shift - 4, val, i, s + 4);
1982             else if (s[2] == 'N')
1983               for (j = 0; j < 4; j++)
1984                 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1985             else if (s[2] == 'x')
1986               for (j = 0; j < 4; j += 2)
1987                 for (m = 0; m < 32; m++)
1988                   {
1989                     /* Ignore illegal nopy */
1990                     if ((m & 7) == 0 && m != 0)
1991                       continue;
1992                     mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
1993                     expand_opcode (shift - 4, val | mv | (j << shift), i,
1994                                    s + 4);
1995                   }
1996             else if (s[2] == 'y')
1997               for (j = 0; j < 2; j++)
1998                 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1999             break;
2000           }
2001         case 'n':
2002         case 'm':
2003           for (j = 0; j < 16; j++)
2004             {
2005               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2006
2007             }
2008           break;
2009         case 'M':
2010           /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2011           for (j = 5; j < 16; j++)
2012             if (j != 6)
2013               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2014           break;
2015         case 'G':
2016           /* A1G, A0G: */
2017           for (j = 13; j <= 15; j +=2)
2018             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2019           break;
2020         case 's':
2021           /* System registers mach, macl, pr: */
2022           for (j = 0; j < 3; j++)
2023             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2024           /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2025           for (j = 5; j < 12; j++)
2026             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2027           break;
2028         case 'X':
2029         case 'a':
2030           val |= bton (s) << shift;
2031           for (j = 0; j < 16; j += 8)
2032             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2033           break;
2034         case 'Y':
2035         case 'A':
2036           val |= bton (s) << shift;
2037           for (j = 0; j < 8; j += 4)
2038             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2039           break;
2040
2041         default:
2042           for (j = 0; j < (1 << (shift + 4)); j++)
2043             {
2044               table[val | j] = i;
2045             }
2046         }
2047     }
2048 }
2049
2050 /* Print the jump table used to index an opcode into a switch
2051    statement entry. */
2052
2053 static void
2054 dumptable (name, size, start)
2055      char *name;
2056      int size;
2057      int start;
2058 {
2059   int lump = 256;
2060   int online = 16;
2061
2062   int i = start;
2063
2064   printf ("unsigned char %s[%d]={\n", name, size);
2065   while (i < start + size)
2066     {
2067       int j = 0;
2068
2069       printf ("/* 0x%x */\n", i);
2070
2071       while (j < lump)
2072         {
2073           int k = 0;
2074           while (k < online)
2075             {
2076               printf ("%2d", table[i + j + k]);
2077               if (j + k < lump)
2078                 printf (",");
2079
2080               k++;
2081             }
2082           j += k;
2083           printf ("\n");
2084         }
2085       i += j;
2086     }
2087   printf ("};\n");
2088 }
2089
2090
2091 static void
2092 filltable (p)
2093      op *p;
2094 {
2095   static int index = 1;
2096
2097   sorttab ();
2098   for (; p->name; p++)
2099     {
2100       p->index = index++;
2101       expand_opcode (12, 0, p->index, p->code);
2102     }
2103 }
2104
2105 /* Table already contais all the switch case tags for 16-bit opcode double
2106    data transfer (ddt) insns, and the switch case tag for processing parallel
2107    processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
2108    latter tag to represent all combinations of ppi with ddt.  */
2109 static void
2110 ppi_moves ()
2111 {
2112   int i;
2113
2114   for (i = 0xf000; i < 0xf400; i++)
2115     if (table[i])
2116       table[i + 0x800] = table[0xf800];
2117 }
2118
2119 static void
2120 gensim_caselist (p)
2121      op *p;
2122 {
2123   for (; p->name; p++)
2124     {
2125       int j;
2126       int sextbit = -1;
2127       int needm = 0;
2128       int needn = 0;
2129       
2130       char *s = p->code;
2131
2132       printf ("  /* %s %s */\n", p->name, p->code);
2133       printf ("  case %d:      \n", p->index);
2134
2135       printf ("    {\n");
2136       while (*s)
2137         {
2138           switch (*s)
2139             {
2140             case '0':
2141             case '1':
2142               s += 2;
2143               break;
2144             case '.':
2145               s += 4;
2146               break;
2147             case 'n':
2148               printf ("      int n = (iword >>8) & 0xf;\n");
2149               needn = 1;
2150               s += 4;
2151               break;
2152             case 'N':
2153               printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2154               s += 2;
2155               break;
2156             case 'x':
2157               printf ("      int n = ((iword >> 9) & 1) + 4;\n");
2158               needn = 1;
2159               s += 2;
2160               break;
2161             case 'y':
2162               printf ("      int n = ((iword >> 8) & 1) + 4;\n");
2163               needn = 1;
2164               s += 2;
2165               break;
2166             case 'm':
2167               needm = 1;
2168             case 's':
2169             case 'M':
2170             case 'G':
2171               printf ("      int m = (iword >>4) & 0xf;\n");
2172               s += 4;
2173               break;
2174             case 'X':
2175               printf ("      int m = ((iword >> 7) & 1) + 8;\n");
2176               s += 2;
2177               break;
2178             case 'a':
2179               printf ("      int m = 7 - ((iword >> 6) & 2);\n");
2180               s += 2;
2181               break;
2182             case 'Y':
2183               printf ("      int m = ((iword >> 6) & 1) + 10;\n");
2184               s += 2;
2185               break;
2186             case 'A':
2187               printf ("      int m = 7 - ((iword >> 5) & 2);\n");
2188               s += 2;
2189               break;
2190
2191             case 'i':
2192               printf ("      int i = (iword & 0x");
2193
2194               switch (s[1])
2195                 {
2196                 case '4':
2197                   printf ("f");
2198                   break;
2199                 case '8':
2200                   printf ("ff");
2201                   break;
2202                 case '1':
2203                   sextbit = 12;
2204
2205                   printf ("fff");
2206                   break;
2207                 }
2208               printf (")");
2209
2210               switch (s[3])
2211                 {
2212                 case '1':
2213                   break;
2214                 case '2':
2215                   printf ("<<1");
2216                   break;
2217                 case '4':
2218                   printf ("<<2");
2219                   break;
2220                 }
2221               printf (";\n");
2222               s += 4;
2223             }
2224         }
2225       if (sextbit > 0)
2226         {
2227           printf ("      i = (i ^ (1<<%d))-(1<<%d);\n",
2228                   sextbit - 1, sextbit - 1);
2229         }
2230
2231       if (needm && needn)
2232         printf ("      TB(m,n);\n");  
2233       else if (needm)
2234         printf ("      TL(m);\n");
2235       else if (needn)
2236         printf ("      TL(n);\n");
2237
2238       {
2239         /* Do the refs */
2240         char *r;
2241         for (r = p->refs; *r; r++)
2242           {
2243             if (*r == '0') printf("      CREF(0);\n"); 
2244             if (*r == '8') printf("      CREF(8);\n"); 
2245             if (*r == '9') printf("      CREF(9);\n"); 
2246             if (*r == 'n') printf("      CREF(n);\n"); 
2247             if (*r == 'm') printf("      CREF(m);\n"); 
2248           }
2249       }
2250
2251       printf ("      {\n");
2252       for (j = 0; j < MAX_NR_STUFF; j++)
2253         {
2254           if (p->stuff[j])
2255             {
2256               printf ("        %s\n", p->stuff[j]);
2257             }
2258         }
2259       printf ("      }\n");
2260
2261       {
2262         /* Do the defs */
2263         char *r;
2264         for (r = p->defs; *r; r++) 
2265           {
2266             if (*r == '0') printf("      CDEF(0);\n"); 
2267             if (*r == 'n') printf("      CDEF(n);\n"); 
2268             if (*r == 'm') printf("      CDEF(m);\n"); 
2269           }
2270       }
2271
2272       printf ("      break;\n");
2273       printf ("    }\n");
2274     }
2275 }
2276
2277 static void
2278 gensim ()
2279 {
2280   printf ("{\n");
2281   printf ("  switch (jump_table[iword]) {\n");
2282
2283   gensim_caselist (tab);
2284   gensim_caselist (movsxy_tab);
2285
2286   printf ("  default:\n");
2287   printf ("    {\n");
2288   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2289   printf ("    }\n");
2290   printf ("  }\n");
2291   printf ("}\n");
2292 }
2293
2294 static void
2295 gendefines ()
2296 {
2297   op *p;
2298   filltable (tab);
2299   for (p = tab; p->name; p++)
2300     {
2301       char *s = p->name;
2302       printf ("#define OPC_");
2303       while (*s) {
2304         if (isupper(*s)) 
2305           *s = tolower(*s);
2306         if (isalpha(*s)) printf("%c", *s);
2307         if (*s == ' ') printf("_");
2308         if (*s == '@') printf("ind_");
2309         if (*s == ',') printf("_");
2310         s++;
2311       }
2312       printf(" %d\n",p->index);
2313     }
2314 }
2315
2316 static int ppi_index;
2317
2318 /* Take an ppi code, expand all varying fields in it and fill all the
2319    right entries in 'table' with the opcode index.  */
2320
2321 static void
2322 expand_ppi_code (val, i, s)
2323      int val;
2324      int i;
2325      char *s;
2326 {
2327   int j;
2328
2329   for (;;)
2330     {
2331       switch (s[0])
2332         {
2333         /* The last eight bits are disregarded for the switch table.  */
2334         case 'm':
2335         case 'x':
2336         case '.':
2337           table[val] = i;
2338           return;
2339         case '0':
2340           val += val;
2341           s++;
2342           break;
2343         case '1':
2344           val += val + 1;
2345           s++;
2346           break;
2347         case 'i':
2348         case 'e': case 'f':
2349           val += val;
2350           s++;
2351           expand_ppi_code (val, i, s);
2352           val++;
2353           break;
2354         case 'c':
2355           val <<= 2;
2356           s += 2;
2357           val++;
2358           expand_ppi_code (val, ppi_index++, s);
2359           val++;
2360           expand_ppi_code (val, i, s);
2361           val++;
2362           break;
2363         }
2364     }
2365 }
2366
2367 static void
2368 ppi_filltable ()
2369 {
2370   op *p;
2371   ppi_index = 1;
2372
2373   for (p = ppi_tab; p->name; p++)
2374     {
2375       p->index = ppi_index++;
2376       expand_ppi_code (0, p->index, p->code);
2377     }
2378 }
2379
2380 static void
2381 ppi_gensim ()
2382 {
2383   op *p = ppi_tab;
2384
2385   printf ("#define DSR_MASK_G 0x80\n");
2386   printf ("#define DSR_MASK_Z 0x40\n");
2387   printf ("#define DSR_MASK_N 0x20\n");
2388   printf ("#define DSR_MASK_V 0x10\n");
2389   printf ("\n");
2390   printf ("#define COMPUTE_OVERFLOW do {\\\n");
2391   printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2392   printf ("  if (overflow && S) \\\n");
2393   printf ("    { \\\n");
2394   printf ("      if (res_grd & 0x80) \\\n");
2395   printf ("        { \\\n");
2396   printf ("          res = 0x80000000; \\\n");
2397   printf ("          res_grd |=  0xff; \\\n");
2398   printf ("        } \\\n");
2399   printf ("      else \\\n");
2400   printf ("        { \\\n");
2401   printf ("          res = 0x7fffffff; \\\n");
2402   printf ("          res_grd &= ~0xff; \\\n");
2403   printf ("        } \\\n");
2404   printf ("      overflow = 0; \\\n");
2405   printf ("    } \\\n");
2406   printf ("} while (0)\n");
2407   printf ("\n");
2408   printf ("#define ADD_SUB_GE \\\n");
2409   printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2410   printf ("\n");
2411   printf ("static void\n");
2412   printf ("ppi_insn (iword)\n");
2413   printf ("     int iword;\n");
2414   printf ("{\n");
2415   printf ("  static char e_tab[] = { 8,  9, 10,  5};\n");
2416   printf ("  static char f_tab[] = {10, 11,  8,  5};\n");
2417   printf ("  static char x_tab[] = { 8,  9,  7,  5};\n");
2418   printf ("  static char y_tab[] = {10, 11, 12, 14};\n");
2419   printf ("  static char g_tab[] = {12, 14,  7,  5};\n");
2420   printf ("  static char u_tab[] = { 8, 10,  7,  5};\n");
2421   printf ("\n");
2422   printf ("  int z;\n");
2423   printf ("  int res, res_grd;\n");
2424   printf ("  int carry, overflow, greater_equal;\n");
2425   printf ("\n");
2426   printf ("  switch (ppi_table[iword >> 8]) {\n");
2427
2428   for (; p->name; p++)
2429     {
2430       int shift, j;
2431       int cond = 0;
2432       int havedecl = 0;
2433       
2434       char *s = p->code;
2435
2436       printf ("  /* %s %s */\n", p->name, p->code);
2437       printf ("  case %d:      \n", p->index);
2438
2439       printf ("    {\n");
2440       for (shift = 16; *s; )
2441         {
2442           switch (*s)
2443             {
2444             case 'i':
2445               printf ("      int i = (iword >> 4) & 0x7f;\n");
2446               s += 6;
2447               break;
2448             case 'e':
2449             case 'f':
2450             case 'x':
2451             case 'y':
2452             case 'g':
2453             case 'u':
2454               shift -= 2;
2455               printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
2456                       *s, *s, shift);
2457               havedecl = 1;
2458               s += 2;
2459               break;
2460             case 'c':
2461               printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2462               printf ("\tbreak;\n");
2463               printf ("    }\n");
2464               printf ("  case %d:      \n", p->index + 1);
2465               printf ("    {\n");
2466               cond = 1;
2467             case '0':
2468             case '1':
2469             case '.':
2470               shift -= 2;
2471               s += 2;
2472               break;
2473             case 'z':
2474               if (havedecl)
2475                 printf ("\n");
2476               printf ("      z = iword & 0xf;\n");
2477               havedecl = 2;
2478               s += 4;
2479               break;
2480             }
2481         }
2482       if (havedecl == 1)
2483         printf ("\n");
2484       else if (havedecl == 2)
2485         printf ("      {\n");
2486       for (j = 0; j < MAX_NR_STUFF; j++)
2487         {
2488           if (p->stuff[j])
2489             {
2490               printf ("      %s%s\n",
2491                       (havedecl == 2 ? "  " : ""),
2492                       p->stuff[j]);
2493             }
2494         }
2495       if (havedecl == 2)
2496         printf ("      }\n");
2497       if (cond)
2498         {
2499           printf ("      if (iword & 0x200)\n");
2500           printf ("        goto assign_z;\n");
2501         }
2502       printf ("      break;\n");
2503       printf ("    }\n");
2504     }
2505
2506   printf ("  default:\n");
2507   printf ("    {\n");
2508   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2509   printf ("      return;\n");
2510   printf ("    }\n");
2511   printf ("  }\n");
2512   printf ("  DSR &= ~0xf1;\n");
2513   printf ("  if (res || res_grd)\n");
2514   printf ("    DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2515   printf ("  else\n");
2516   printf ("    DSR |= DSR_MASK_Z | overflow;\n");
2517   printf (" assign_dc:\n");
2518   printf ("  switch (DSR >> 1 & 7)\n");
2519   printf ("    {\n");
2520   printf ("    case 0: /* Carry Mode */\n");
2521   printf ("      DSR |= carry;\n");
2522   printf ("    case 1: /* Negative Value Mode */\n");
2523   printf ("      DSR |= res_grd >> 7 & 1;\n");
2524   printf ("    case 2: /* Zero Value Mode */\n");
2525   printf ("      DSR |= DSR >> 6 & 1;\n");
2526   printf ("    case 3: /* Overflow mode\n");
2527   printf ("      DSR |= overflow >> 4;\n");
2528   printf ("    case 4: /* Signed Greater Than Mode */\n");
2529   printf ("      DSR |= DSR >> 7 & 1;\n");
2530   printf ("    case 4: /* Signed Greater Than Or Equal Mode */\n");
2531   printf ("      DSR |= greater_equal >> 7;\n");
2532   printf ("    }\n");
2533   printf (" assign_z:\n");
2534   printf ("  if (0xa05f >> z & 1)\n");
2535   printf ("    {\n");
2536   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2537   printf ("      return;\n");
2538   printf ("    }\n");
2539   printf ("  DSP_R (z) = res;\n");
2540   printf ("  DSP_GRD (z) = res_grd;\n");
2541   printf ("}\n");
2542 }
2543
2544 int
2545 main (ac, av)
2546      int ac;
2547      char **av;
2548 {
2549   /* verify the table before anything else */
2550   {
2551     op *p;
2552     for (p = tab; p->name; p++)
2553       {
2554         /* check that the code field contains 16 bits */
2555         if (strlen (p->code) != 16)
2556           {
2557             fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2558                      p->code, strlen (p->code), p->name);
2559             abort ();
2560           }
2561       }
2562   }
2563
2564   /* now generate the requested data */
2565   if (ac > 1)
2566     {
2567       if (strcmp (av[1], "-t") == 0)
2568         {
2569           gengastab ();
2570         }
2571       else if (strcmp (av[1], "-d") == 0)
2572         {
2573           gendefines ();
2574         }
2575       else if (strcmp (av[1], "-s") == 0)
2576         {
2577           filltable (tab);
2578           dumptable ("sh_jump_table", 1 << 16, 0);
2579
2580           memset (table, 0, sizeof table);
2581           filltable (movsxy_tab);
2582           ppi_moves ();
2583           dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2584
2585           memset (table, 0, sizeof table);
2586           ppi_filltable ();
2587           dumptable ("ppi_table", 1 << 8, 0);
2588         }
2589       else if (strcmp (av[1], "-x") == 0)
2590         {
2591           filltable (tab);
2592           filltable (movsxy_tab);
2593           gensim ();
2594         }
2595       else if (strcmp (av[1], "-p") == 0)
2596         {
2597           ppi_filltable ();
2598           ppi_gensim ();
2599         }
2600     }
2601   else
2602     fprintf (stderr, "Opcode table generation no longer supported.\n");
2603   return 0;
2604 }