* pendanticism
[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,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 = PC;",
955     "trap (0xc3, R0, 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 #if 0
1033     /* SH-[12] */
1034     "long imm = 0xff & i;",
1035     "if (i==0xc3)",
1036     "  PC-=2;",
1037     "if (i<20||i==34||i==0xc3)",
1038     "  trap(i,R,memory,maskl,maskw,endianw);",
1039     "else {",
1040     "  R[15]-=4;",
1041     "  WLAT(R[15],GET_SR());",
1042     "  R[15]-=4;",
1043     "  WLAT(R[15],PC+2);",
1044     "  PC=RLAT(VBR+(imm<<2))-2;",
1045     "}",
1046 #else
1047     "if (i == 0xc3)",
1048     "  {",
1049     "    nip = PC;",
1050     "    trap (i, R, memory, maskl, maskw,endianw);",
1051     "  }",
1052     "else if (i < 20 || i==34 || i==0xc3)",
1053     "  trap (i, R, memory, maskl, maskw,endianw);",
1054     "else if (!SR_BL) {",
1055     "  /* FIXME: TRA = (imm << 2); */",
1056     "  SSR = GET_SR();",
1057     "  SPC = PH2T (PC + 2);",
1058     "  SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1059     "  /* FIXME: EXPEVT = 0x00000160; */",
1060     "  SET_NIP (PT2H (VBR + 0x00000100));",
1061     "}",
1062 #endif
1063   },
1064
1065   { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1066     "SET_SR_T ((R[n] & R[m]) == 0);",
1067   },
1068   { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1069     "SET_SR_T ((R0 & i) == 0);",
1070   },
1071   { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1072     "MA (1);",
1073     "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1074   },
1075
1076   { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1077     "R0 ^= i;",
1078   },
1079   { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1080     "R[n] ^= R[m];",
1081   },
1082   { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1083     "MA (1);",
1084     "ult = RBAT (GBR+R0);",
1085     "ult ^= i;",
1086     "WBAT (GBR + R0, ult);",
1087   },
1088
1089   { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1090     "R[n] = (((R[n] >> 16) & 0xffff)",
1091     "        | ((R[m] << 16) & 0xffff0000));",
1092   },
1093
1094 #if 0
1095   { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1096     "divl(0,R[n],R[m]);",
1097   },
1098   { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1099     "divl(0,R[n],R[m]);",
1100   },
1101 #endif
1102
1103   {0, 0}};
1104
1105 op movsxy_tab[] =
1106 {
1107 /* If this is disabled, the simulator speeds up by about 12% on a
1108    450 MHz PIII - 9% with ACE_FAST.
1109    Maybe we should have separate simulator loops?  */
1110 #if 1
1111   { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1112     "MA (1);",
1113     "R[n] -= 2;",
1114     "DSP_R (m) = RSWAT (R[n]) << 16;",
1115     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1116   },
1117   { "", "n",  "movs.w @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0100",
1118     "MA (1);",
1119     "DSP_R (m) = RSWAT (R[n]) << 16;",
1120     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1121   },
1122   { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1123     "MA (1);",
1124     "DSP_R (m) = RSWAT (R[n]) << 16;",
1125     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1126     "R[n] += 2;",
1127   },
1128   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1129     "MA (1);",
1130     "DSP_R (m) = RSWAT (R[n]) << 16;",
1131     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1132     "R[n] += R[8];",
1133   },
1134   { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1135     "MA (1);",
1136     "R[n] -= 2;",
1137     "DSP_R (m) = RSWAT (R[n]);",
1138   },
1139   { "", "n",  "movs.w @<REG_N>,<DSP_GRD_M>",  "111101NNGGGG0100",
1140     "MA (1);",
1141     "DSP_R (m) = RSWAT (R[n]);",
1142   },
1143   { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1144     "MA (1);",
1145     "DSP_R (m) = RSWAT (R[n]);",
1146     "R[n] += 2;",
1147   },
1148   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1149     "MA (1);",
1150     "DSP_R (m) = RSWAT (R[n]);",
1151     "R[n] += R[8];",
1152   },
1153   { "n", "n", "<DSP_REG_M>,movs.w @-<REG_N>", "111101NNMMMM0001",
1154     "MA (1);",
1155     "R[n] -= 2;",
1156     "WWAT (R[n], DSP_R (m) >> 16);",
1157   },
1158   { "", "n",  "movs.w <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0101",
1159     "MA (1);",
1160     "WWAT (R[n], DSP_R (m) >> 16);",
1161   },
1162   { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1163     "MA (1);",
1164     "WWAT (R[n], DSP_R (m) >> 16);",
1165     "R[n] += 2;",
1166   },
1167   { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1168     "MA (1);",
1169     "WWAT (R[n], DSP_R (m) >> 16);",
1170     "R[n] += R[8];",
1171   },
1172   { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1173     "MA (1);",
1174     "R[n] -= 2;",
1175     "WWAT (R[n], SEXT (DSP_R (m)));",
1176   },
1177   { "", "n",  "movs.w <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0101",
1178     "MA (1);",
1179     "WWAT (R[n], SEXT (DSP_R (m)));",
1180   },
1181   { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1182     "MA (1);",
1183     "WWAT (R[n], SEXT (DSP_R (m)));",
1184     "R[n] += 2;",
1185   },
1186   { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1187     "MA (1);",
1188     "WWAT (R[n], SEXT (DSP_R (m)));",
1189     "R[n] += R[8];",
1190   },
1191   { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1192     "MA (1);",
1193     "R[n] -= 4;",
1194     "DSP_R (m) = RLAT (R[n]);",
1195     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1196   },
1197   { "", "n",  "movs.l @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0110",
1198     "MA (1);",
1199     "DSP_R (m) = RLAT (R[n]);",
1200     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1201   },
1202   { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1203     "MA (1);",
1204     "DSP_R (m) = RLAT (R[n]);",
1205     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1206     "R[n] += 4;",
1207   },
1208   { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1209     "MA (1);",
1210     "DSP_R (m) = RLAT (R[n]);",
1211     "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1212     "R[n] += R[8];",
1213   },
1214   { "n", "n", "<DSP_REG_M>,movs.l @-<REG_N>", "111101NNMMMM0011",
1215     "MA (1);",
1216     "R[n] -= 4;",
1217     "WLAT (R[n], DSP_R (m));",
1218   },
1219   { "", "n",  "movs.l <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0111",
1220     "MA (1);",
1221     "WLAT (R[n], DSP_R (m));",
1222   },
1223   { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1224     "MA (1);",
1225     "WLAT (R[n], DSP_R (m));",
1226     "R[n] += 4;",
1227   },
1228   { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1229     "MA (1);",
1230     "WLAT (R[n], DSP_R (m));",
1231     "R[n] += R[8];",
1232   },
1233   { "n", "n", "<DSP_GRD_M>,movs.l @-<REG_N>", "111101NNGGGG0011",
1234     "MA (1);",
1235     "R[n] -= 4;",
1236     "WLAT (R[n], SEXT (DSP_R (m)));",
1237   },
1238   { "", "n",  "movs.l <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0111",
1239     "MA (1);",
1240     "WLAT (R[n], SEXT (DSP_R (m)));",
1241   },
1242   { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1243     "MA (1);",
1244     "WLAT (R[n], SEXT (DSP_R (m)));",
1245     "R[n] += 4;",
1246   },
1247   { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1248     "MA (1);",
1249     "WLAT (R[n], SEXT (DSP_R (m)));",
1250     "R[n] += R[8];",
1251   },
1252   { "", "n", "movx.w @<REG_x>,<DSP_XX>",   "111100xxXX000100",
1253     "DSP_R (m) = RSWAT (R[n]) << 16;",
1254     "iword &= 0xfd53; goto top;",
1255   },
1256   { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1257     "DSP_R (m) = RSWAT (R[n]) << 16;",
1258     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1259     "iword &= 0xfd53; goto top;",
1260   },
1261   { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1262     "DSP_R (m) = RSWAT (R[n]) << 16;",
1263     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1264     "iword &= 0xfd53; goto top;",
1265   },
1266   { "", "n", "movx.w <DSP_Aa>,@<REG_x>",   "111100xxaa100100",
1267     "WWAT (R[n], DSP_R (m) >> 16);",
1268     "iword &= 0xfd53; goto top;",
1269   },
1270   { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1271     "WWAT (R[n], DSP_R (m) >> 16);",
1272     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1273     "iword &= 0xfd53; goto top;",
1274   },
1275   { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101000",
1276     "WWAT (R[n], DSP_R (m) >> 16);",
1277     "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1278     "iword &= 0xfd53; goto top;",
1279   },
1280   { "", "n", "movy.w @<REG_y>,<DSP_YY>",   "111100yyYY000001",
1281     "DSP_R (m) = RSWAT (R[n]) << 16;",
1282   },
1283   { "n", "n", "movy.w @<REG_x>+,<DSP_YY>", "111100yyYY000010",
1284     "DSP_R (m) = RSWAT (R[n]) << 16;",
1285     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1286   },
1287   { "n", "n9","movy.w @<REG_x>+REG_9,<DSP_YY>", "111100yyYY000010",
1288     "DSP_R (m) = RSWAT (R[n]) << 16;",
1289     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1290   },
1291   { "", "n", "movy.w <DSP_Aa>,@<REG_x>",   "111100yyAA010001",
1292     "WWAT (R[n], DSP_R (m) >> 16);",
1293   },
1294   { "n", "n", "movy.w <DSP_Aa>,@<REG_x>+", "111100yyAA010010",
1295     "WWAT (R[n], DSP_R (m) >> 16);",
1296     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1297   },
1298   { "n", "n9", "movy.w <DSP_Aa>,@<REG_x>+REG_9", "111100yyAA010010",
1299     "WWAT (R[n], DSP_R (m) >> 16);",
1300     "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1301   },
1302   { "", "", "nopx nopy", "1111000000000000",
1303     "/* nop */",
1304   },
1305   { "", "", "ppi", "1111100000000000",
1306     "ppi_insn (RIAT (nip));",
1307     "nip += 2;",
1308     "iword &= 0xf7ff; goto top;",
1309   },
1310 #endif
1311   {0, 0}};
1312
1313 op ppi_tab[] =
1314 {
1315   { "","", "pshl #<imm>,dz",    "00000iiim16.zzzz",
1316     "int Sz = DSP_R (z) & 0xffff0000;",
1317     "",
1318     "if (i < 16)",
1319     "  res = Sz << i;",
1320     "else if (i >= 128 - 16)",
1321     "  res = Sz >> 128 - i;",
1322     "else",
1323     "  {",
1324     "    RAISE_EXCEPTION (SIGILL);",
1325     "    return;",
1326     "  }",
1327     "res &= 0xffff0000;",
1328     "res_grd = 0;",
1329     "goto logical;",
1330   },
1331   { "","", "psha #<imm>,dz",    "00010iiim32.zzzz",
1332     "int Sz = DSP_R (z);",
1333     "int Sz_grd = GET_DSP_GRD (z);",
1334     "",
1335     "if (i < 32)",
1336     "  {",
1337     "    if (i == 32)",
1338     "      {",
1339     "        res = 0;",
1340     "        res_grd = Sz;",
1341     "      }",
1342     "    else",
1343     "      {",
1344     "        res = Sz << i;",
1345     "        res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1346     "      }",
1347     "    res_grd = SEXT (res_grd);",
1348     "    carry = res_grd & 1;",
1349     "  }",
1350     "else if (i >= 96)",
1351     "  {",
1352     "    i = 128 - i;",
1353     "    if (i == 32)",
1354     "      {",
1355     "        res_grd = SIGN32 (Sz_grd);",
1356     "        res = Sz_grd;",
1357     "      }",
1358     "    else",
1359     "      {",
1360     "        res = Sz >> i | Sz_grd << 32 - i;",
1361     "        res_grd = Sz_grd >> i;",
1362     "      }",
1363     "    carry = Sz >> (i - 1) & 1;",
1364     "  }",
1365     "else",
1366     "  {",
1367     "    RAISE_EXCEPTION (SIGILL);",
1368     "    return;",
1369     "  }",
1370     "COMPUTE_OVERFLOW;",
1371     "greater_equal = 0;",
1372   },
1373   { "","", "pmuls Se,Sf,Dg",    "0100eeffxxyygguu",
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     "return;",
1380   },
1381   { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg",      "0110eeffxxyygguu",
1382     "int Sx = DSP_R (x);",
1383     "int Sx_grd = GET_DSP_GRD (x);",
1384     "int Sy = DSP_R (y);",
1385     "int Sy_grd = SIGN32 (Sy);",
1386     "",
1387     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1388     "if (res == 0x80000000)",
1389     "  res = 0x7fffffff;",
1390     "DSP_R (g) = res;",
1391     "DSP_GRD (g) = SIGN32 (res);",
1392     "",
1393     "z = u;",
1394     "res = Sx - Sy;",
1395     "carry = (unsigned) res > (unsigned) Sx;",
1396     "res_grd = Sx_grd - Sy_grd - carry;",
1397     "COMPUTE_OVERFLOW;",
1398     "ADD_SUB_GE;",
1399   },
1400   { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg",      "0111eeffxxyygguu",
1401     "int Sx = DSP_R (x);",
1402     "int Sx_grd = GET_DSP_GRD (x);",
1403     "int Sy = DSP_R (y);",
1404     "int Sy_grd = SIGN32 (Sy);",
1405     "",
1406     "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1407     "if (res == 0x80000000)",
1408     "  res = 0x7fffffff;",
1409     "DSP_R (g) = res;",
1410     "DSP_GRD (g) = SIGN32 (res);",
1411     "",
1412     "z = u;",
1413     "res = Sx + Sy;",
1414     "carry = (unsigned) res < (unsigned) Sx;",
1415     "res_grd = Sx_grd + Sy_grd + carry;",
1416     "COMPUTE_OVERFLOW;",
1417   },
1418   { "","", "psubc Sx,Sy,Dz",            "10100000xxyyzzzz",
1419     "int Sx = DSP_R (x);",
1420     "int Sx_grd = GET_DSP_GRD (x);",
1421     "int Sy = DSP_R (y);",
1422     "int Sy_grd = SIGN32 (Sy);",
1423     "",
1424     "res = Sx - Sy - (DSR & 1);",
1425     "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1426     "res_grd = Sx_grd + Sy_grd + carry;",
1427     "COMPUTE_OVERFLOW;",
1428     "ADD_SUB_GE;",
1429     "DSR &= ~0xf1;\n",
1430     "if (res || res_grd)\n",
1431     "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1432     "else\n",
1433     "  DSR |= DSR_MASK_Z | overflow;\n",
1434     "DSR |= carry;\n",
1435     "goto assign_z;\n",
1436   },
1437   { "","", "paddc Sx,Sy,Dz",    "10110000xxyyzzzz",
1438     "int Sx = DSP_R (x);",
1439     "int Sx_grd = GET_DSP_GRD (x);",
1440     "int Sy = DSP_R (y);",
1441     "int Sy_grd = SIGN32 (Sy);",
1442     "",
1443     "res = Sx + Sy + (DSR & 1);",
1444     "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1445     "res_grd = Sx_grd + Sy_grd + carry;",
1446     "COMPUTE_OVERFLOW;",
1447     "ADD_SUB_GE;",
1448     "DSR &= ~0xf1;\n",
1449     "if (res || res_grd)\n",
1450     "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1451     "else\n",
1452     "  DSR |= DSR_MASK_Z | overflow;\n",
1453     "DSR |= carry;\n",
1454     "goto assign_z;\n",
1455   },
1456   { "","", "pcmp Sx,Sy",        "10000100xxyy....",
1457     "int Sx = DSP_R (x);",
1458     "int Sx_grd = GET_DSP_GRD (x);",
1459     "int Sy = DSP_R (y);",
1460     "int Sy_grd = SIGN32 (Sy);",
1461     "",
1462     "z = 17; /* Ignore result.  */",
1463     "res = Sx - Sy;",
1464     "carry = (unsigned) res > (unsigned) Sx;",
1465     "res_grd = Sx_grd - Sy_grd - carry;",
1466     "COMPUTE_OVERFLOW;",
1467     "ADD_SUB_GE;",
1468   },
1469   { "","", "pwsb Sx,Sy,Dz",     "10100100xxyyzzzz",
1470   },
1471   { "","", "pwad Sx,Sy,Dz",     "10110100xxyyzzzz",
1472   },
1473   { "","", "pabs Sx,Dz",        "10001000xx..zzzz",
1474     "res = DSP_R (x);",
1475     "res_grd = GET_DSP_GRD (x);",
1476     "if (res >= 0)",
1477     "  carry = 0;",
1478     "else",
1479     "  {",
1480     "    res = -res;",
1481     "    carry = (res != 0); /* The manual has a bug here.  */", 
1482     "    res_grd = -res_grd - carry;", 
1483     "  }",
1484     "COMPUTE_OVERFLOW;",
1485     "/* ??? The re-computing of overflow after",
1486     "   saturation processing is specific to pabs.  */",
1487     "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1488     "ADD_SUB_GE;",
1489   },
1490   { "","", "prnd Sx,Dz",        "10011000xx..zzzz",
1491     "int Sx = DSP_R (x);",
1492     "int Sx_grd = GET_DSP_GRD (x);",
1493     "",
1494     "res = Sx + 0x8000;",
1495     "carry = (unsigned) res < (unsigned) Sx;",
1496     "res_grd = Sx_grd + carry;",
1497     "COMPUTE_OVERFLOW;",
1498     "ADD_SUB_GE;",
1499   },
1500   { "","", "pabs Sy,Dz",        "10101000..yyzzzz",
1501     "res = DSP_R (y);",
1502     "res_grd = 0;",
1503     "overflow = 0;",
1504     "greater_equal = DSR_MASK_G;",
1505     "if (res >= 0)",
1506     "  carry = 0;",
1507     "else",
1508     "  {",
1509     "    res = -res;",
1510     "    carry = 1;",
1511     "    if (res < 0)",
1512     "      {",
1513     "        if (S)",
1514     "          res = 0x7fffffff;",
1515     "        else",
1516     "          {",
1517     "            overflow = DSR_MASK_V;",
1518     "            greater_equal = 0;",
1519     "          }",
1520     "      }",
1521     "  }",
1522   },
1523   { "","", "prnd Sy,Dz",        "10111000..yyzzzz",
1524     "int Sy = DSP_R (y);",
1525     "int Sy_grd = SIGN32 (Sy);",
1526     "",
1527     "res = Sy + 0x8000;",
1528     "carry = (unsigned) res < (unsigned) Sy;",
1529     "res_grd = Sy_grd + carry;",
1530     "COMPUTE_OVERFLOW;",
1531     "ADD_SUB_GE;",
1532   },
1533   { "","", "(if cc) pshl Sx,Sy,Dz",     "100000ccxxyyzzzz",
1534     "int Sx = DSP_R (x) & 0xffff0000;",
1535     "int Sy = DSP_R (y) >> 16 & 0x7f;",
1536     "",
1537     "if (Sy < 16)",
1538     "  res = Sx << Sy;",
1539     "else if (Sy >= 128 - 16)",
1540     "  res = Sx >> 128 - Sy;",
1541     "else",
1542     "  {",
1543     "    RAISE_EXCEPTION (SIGILL);",
1544     "    return;",
1545     "  }",
1546     "goto cond_logical;",
1547   },
1548   { "","", "(if cc) psha Sx,Sy,Dz",     "100100ccxxyyzzzz",
1549     "int Sx = DSP_R (x);",
1550     "int Sx_grd = GET_DSP_GRD (x);",
1551     "int Sy = DSP_R (y) >> 16 & 0x7f;",
1552     "",
1553     "if (Sy < 32)",
1554     "  {",
1555     "    if (Sy == 32)",
1556     "      {",
1557     "        res = 0;",
1558     "        res_grd = Sx;",
1559     "      }",
1560     "    else",
1561     "      {",
1562     "        res = Sx << Sy;",
1563     "        res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1564     "      }",
1565     "    res_grd = SEXT (res_grd);",
1566     "    carry = res_grd & 1;",
1567     "  }",
1568     "else if (Sy >= 96)",
1569     "  {",
1570     "    Sy = 128 - Sy;",
1571     "    if (Sy == 32)",
1572     "      {",
1573     "        res_grd = SIGN32 (Sx_grd);",
1574     "        res = Sx_grd;",
1575     "      }",
1576     "    else",
1577     "      {",
1578     "        res = Sx >> Sy | Sx_grd << 32 - Sy;",
1579     "        res_grd = Sx_grd >> Sy;",
1580     "      }",
1581     "    carry = Sx >> (Sy - 1) & 1;",
1582     "  }",
1583     "else",
1584     "  {",
1585     "    RAISE_EXCEPTION (SIGILL);",
1586     "    return;",
1587     "  }",
1588     "COMPUTE_OVERFLOW;",
1589     "greater_equal = 0;",
1590   },
1591   { "","", "(if cc) psub Sx,Sy,Dz",     "101000ccxxyyzzzz",
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) padd Sx,Sy,Dz",     "101100ccxxyyzzzz",
1604     "int Sx = DSP_R (x);",
1605     "int Sx_grd = GET_DSP_GRD (x);",
1606     "int Sy = DSP_R (y);",
1607     "int Sy_grd = SIGN32 (Sy);",
1608     "",
1609     "res = Sx + Sy;",
1610     "carry = (unsigned) res < (unsigned) Sx;",
1611     "res_grd = Sx_grd + Sy_grd + carry;",
1612     "COMPUTE_OVERFLOW;",
1613     "ADD_SUB_GE;",
1614   },
1615   { "","", "(if cc) pand Sx,Sy,Dz",     "100101ccxxyyzzzz",
1616     "res = DSP_R (x) & DSP_R (y);",
1617   "cond_logical:",
1618     "res &= 0xffff0000;",
1619     "res_grd = 0;",
1620     "if (iword & 0x200)\n",
1621     "  goto assign_z;\n",
1622   "logical:",
1623     "carry = 0;",
1624     "overflow = 0;",
1625     "greater_equal = 0;",
1626     "DSR &= ~0xf1;\n",
1627     "if (res)\n",
1628     "  DSR |= res >> 26 & DSR_MASK_N;\n",
1629     "else\n",
1630     "  DSR |= DSR_MASK_Z;\n",
1631     "goto assign_dc;\n",
1632   },
1633   { "","", "(if cc) pxor Sx,Sy,Dz",     "101001ccxxyyzzzz",
1634     "res = DSP_R (x) ^ DSP_R (y);",
1635     "goto cond_logical;",
1636   },
1637   { "","", "(if cc) por Sx,Sy,Dz",      "101101ccxxyyzzzz",
1638     "res = DSP_R (x) | DSP_R (y);",
1639     "goto cond_logical;",
1640   },
1641   { "","", "(if cc) pdec Sx,Dz",        "100010ccxx..zzzz",
1642     "int Sx = DSP_R (x);",
1643     "int Sx_grd = GET_DSP_GRD (x);",
1644     "",
1645     "res = Sx - 0x10000;",
1646     "carry = res > Sx;",
1647     "res_grd = Sx_grd - carry;",
1648     "COMPUTE_OVERFLOW;",
1649     "ADD_SUB_GE;",
1650     "res &= 0xffff0000;",
1651   },
1652   { "","", "(if cc) pinc Sx,Dz",        "100110ccxx..zzzz",
1653     "int Sx = DSP_R (x);",
1654     "int Sx_grd = GET_DSP_GRD (x);",
1655     "",
1656     "res = Sx + 0x10000;",
1657     "carry = res < Sx;",
1658     "res_grd = Sx_grd + carry;",
1659     "COMPUTE_OVERFLOW;",
1660     "ADD_SUB_GE;",
1661     "res &= 0xffff0000;",
1662   },
1663   { "","", "(if cc) pdec Sy,Dz",        "101010cc..yyzzzz",
1664     "int Sy = DSP_R (y);",
1665     "int Sy_grd = SIGN32 (Sy);",
1666     "",
1667     "res = Sy - 0x10000;",
1668     "carry = res > Sy;",
1669     "res_grd = Sy_grd - carry;",
1670     "COMPUTE_OVERFLOW;",
1671     "ADD_SUB_GE;",
1672     "res &= 0xffff0000;",
1673   },
1674   { "","", "(if cc) pinc Sy,Dz",        "101110cc..yyzzzz",
1675     "int Sy = DSP_R (y);",
1676     "int Sy_grd = SIGN32 (Sy);",
1677     "",
1678     "res = Sy + 0x10000;",
1679     "carry = res < Sy;",
1680     "res_grd = Sy_grd + carry;",
1681     "COMPUTE_OVERFLOW;",
1682     "ADD_SUB_GE;",
1683     "res &= 0xffff0000;",
1684   },
1685   { "","", "(if cc) pclr Dz",           "100011cc....zzzz",
1686     "res = 0;",
1687     "res_grd = 0;",
1688     "carry = 0;",
1689     "overflow = 0;",
1690     "greater_equal = 1;",
1691   },
1692   { "","", "(if cc) pdmsb Sx,Dz",       "100111ccxx..zzzz",
1693     "unsigned Sx = DSP_R (x);",
1694     "int Sx_grd = GET_DSP_GRD (x);",
1695     "int i = 16;",
1696     "",
1697     "if (Sx_grd < 0)",
1698     "  {",
1699     "    Sx_grd = ~Sx_grd;",
1700     "    Sx = ~Sx;",
1701     "  }",
1702     "if (Sx_grd)",
1703     "  {",
1704     "    Sx = Sx_grd;",
1705     "    res = -2;",
1706     "  }",
1707     "else if (Sx)",
1708     "  res = 30;",
1709     "else",
1710     "  res = 31;",
1711     "do",
1712     "  {",
1713     "    if (Sx & ~0 << i)",
1714     "      {",
1715     "        res -= i;",
1716     "        Sx >>= i;",
1717     "      }",
1718     "  }",
1719     "while (i >>= 1);",
1720     "res <<= 16;",
1721     "res_grd = SIGN32 (res);",
1722     "carry = 0;",
1723     "overflow = 0;",
1724     "ADD_SUB_GE;",
1725   },
1726   { "","", "(if cc) pdmsb Sy,Dz",       "101111cc..yyzzzz",
1727     "unsigned Sy = DSP_R (y);",
1728     "int i;",
1729     "",
1730     "if (Sy < 0)",
1731     "  Sy = ~Sy;",
1732     "Sy <<= 1;",
1733     "res = 31;",
1734     "do",
1735     "  {",
1736     "    if (Sy & ~0 << i)",
1737     "      {",
1738     "        res -= i;",
1739     "        Sy >>= i;",
1740     "      }",
1741     "  }",
1742     "while (i >>= 1);",
1743     "res <<= 16;",
1744     "res_grd = SIGN32 (res);",
1745     "carry = 0;",
1746     "overflow = 0;",
1747     "ADD_SUB_GE;",
1748   },
1749   { "","", "(if cc) pneg Sx,Dz",        "110010ccxx..zzzz",
1750     "int Sx = DSP_R (x);",
1751     "int Sx_grd = GET_DSP_GRD (x);",
1752     "",
1753     "res = 0 - Sx;",
1754     "carry = res != 0;",
1755     "res_grd = 0 - Sx_grd - carry;",
1756     "COMPUTE_OVERFLOW;",
1757     "ADD_SUB_GE;",
1758   },
1759   { "","", "(if cc) pcopy Sx,Dz",       "110110ccxx..zzzz",
1760     "res = DSP_R (x);",
1761     "res_grd = GET_DSP_GRD (x);",
1762     "carry = 0;",
1763     "COMPUTE_OVERFLOW;",
1764     "ADD_SUB_GE;",
1765   },
1766   { "","", "(if cc) pneg Sy,Dz",        "111010cc..yyzzzz",
1767     "int Sy = DSP_R (y);",
1768     "int Sy_grd = SIGN32 (Sy);",
1769     "",
1770     "res = 0 - Sy;",
1771     "carry = res != 0;",
1772     "res_grd = 0 - Sy_grd - carry;",
1773     "COMPUTE_OVERFLOW;",
1774     "ADD_SUB_GE;",
1775   },
1776   { "","", "(if cc) pcopy Sy,Dz",       "111110cc..yyzzzz",
1777     "res = DSP_R (y);",
1778     "res_grd = SIGN32 (res);",
1779     "carry = 0;",
1780     "COMPUTE_OVERFLOW;",
1781     "ADD_SUB_GE;",
1782   },
1783   { "","", "(if cc) psts MACH,Dz",      "110011cc....zzzz",
1784     "res = MACH;",
1785     "res_grd = SIGN32 (res);",
1786     "goto assign_z;",
1787   },
1788   { "","", "(if cc) psts MACL,Dz",      "110111cc....zzzz",
1789     "res = MACL;",
1790     "res_grd = SIGN32 (res);",
1791     "goto assign_z;",
1792   },
1793   { "","", "(if cc) plds Dz,MACH",      "111011cc....zzzz",
1794     "if (0xa05f >> z & 1)",
1795     "  RAISE_EXCEPTION (SIGILL);",
1796     "else",
1797     "  MACH = DSP_R (z);",
1798     "return;",
1799   },
1800   { "","", "(if cc) plds Dz,MACL",      "111111cc....zzzz",
1801     "if (0xa05f >> z & 1)",
1802     "  RAISE_EXCEPTION (SIGILL);",
1803     "else",
1804     "  MACL = DSP_R (z) = res;",
1805     "return;",
1806   },
1807   {0, 0}
1808 };
1809
1810 /* Tables of things to put into enums for sh-opc.h */
1811 static char *nibble_type_list[] =
1812 {
1813   "HEX_0",
1814   "HEX_1",
1815   "HEX_2",
1816   "HEX_3",
1817   "HEX_4",
1818   "HEX_5",
1819   "HEX_6",
1820   "HEX_7",
1821   "HEX_8",
1822   "HEX_9",
1823   "HEX_A",
1824   "HEX_B",
1825   "HEX_C",
1826   "HEX_D",
1827   "HEX_E",
1828   "HEX_F",
1829   "REG_N",
1830   "REG_M",
1831   "BRANCH_12",
1832   "BRANCH_8",
1833   "DISP_8",
1834   "DISP_4",
1835   "IMM_4",
1836   "IMM_4BY2",
1837   "IMM_4BY4",
1838   "PCRELIMM_8BY2",
1839   "PCRELIMM_8BY4",
1840   "IMM_8",
1841   "IMM_8BY2",
1842   "IMM_8BY4",
1843   0
1844 };
1845 static
1846 char *arg_type_list[] =
1847 {
1848   "A_END",
1849   "A_BDISP12",
1850   "A_BDISP8",
1851   "A_DEC_M",
1852   "A_DEC_N",
1853   "A_DISP_GBR",
1854   "A_DISP_PC",
1855   "A_DISP_REG_M",
1856   "A_DISP_REG_N",
1857   "A_GBR",
1858   "A_IMM",
1859   "A_INC_M",
1860   "A_INC_N",
1861   "A_IND_M",
1862   "A_IND_N",
1863   "A_IND_R0_REG_M",
1864   "A_IND_R0_REG_N",
1865   "A_MACH",
1866   "A_MACL",
1867   "A_PR",
1868   "A_R0",
1869   "A_R0_GBR",
1870   "A_REG_M",
1871   "A_REG_N",
1872   "A_SR",
1873   "A_VBR",
1874   "A_SSR",
1875   "A_SPC",
1876   0,
1877 };
1878
1879 static void
1880 make_enum_list (name, s)
1881      char *name;
1882      char **s;
1883 {
1884   int i = 1;
1885   printf ("typedef enum {\n");
1886   while (*s)
1887     {
1888       printf ("\t%s,\n", *s);
1889       s++;
1890       i++;
1891     }
1892   printf ("} %s;\n", name);
1893 }
1894
1895 static int
1896 qfunc (a, b)
1897      op *a;
1898      op *b;
1899 {
1900   char bufa[9];
1901   char bufb[9];
1902   int diff;
1903
1904   memcpy (bufa, a->code, 4);
1905   memcpy (bufa + 4, a->code + 12, 4);
1906   bufa[8] = 0;
1907
1908   memcpy (bufb, b->code, 4);
1909   memcpy (bufb + 4, b->code + 12, 4);
1910   bufb[8] = 0;
1911   diff = strcmp (bufa, bufb);
1912   /* Stabilize the sort, so that later entries can override more general
1913      preceding entries.  */
1914   return diff ? diff : a - b;
1915 }
1916
1917 static void
1918 sorttab ()
1919 {
1920   op *p = tab;
1921   int len = 0;
1922
1923   while (p->name)
1924     {
1925       p++;
1926       len++;
1927     }
1928   qsort (tab, len, sizeof (*p), qfunc);
1929 }
1930
1931 static void
1932 gengastab ()
1933 {
1934   op *p;
1935   sorttab ();
1936   for (p = tab; p->name; p++)
1937     {
1938       printf ("%s %-30s\n", p->code, p->name);
1939     }
1940
1941
1942 }
1943
1944 /* Convert a string of 4 binary digits into an int */
1945
1946 static
1947 int
1948 bton (s)
1949      char *s;
1950
1951 {
1952   int n = 0;
1953   int v = 8;
1954   while (v)
1955     {
1956       if (*s == '1')
1957         n |= v;
1958       v >>= 1;
1959       s++;
1960     }
1961   return n;
1962 }
1963
1964 static unsigned char table[1 << 16];
1965
1966 /* Take an opcode expand all varying fields in it out and fill all the
1967   right entries in 'table' with the opcode index*/
1968
1969 static void
1970 expand_opcode (shift, val, i, s)
1971      int shift;
1972      int val;
1973      int i;
1974      char *s;
1975 {
1976   int j;
1977
1978   if (*s == 0)
1979     {
1980       table[val] = i;
1981     }
1982   else
1983     {
1984       switch (s[0])
1985         {
1986
1987         case '0':
1988         case '1':
1989           {
1990             int m, mv;
1991
1992             val |= bton (s) << shift;
1993             if (s[2] == '0' || s[2] == '1')
1994               expand_opcode (shift - 4, val, i, s + 4);
1995             else if (s[2] == 'N')
1996               for (j = 0; j < 4; j++)
1997                 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1998             else if (s[2] == 'x')
1999               for (j = 0; j < 4; j += 2)
2000                 for (m = 0; m < 32; m++)
2001                   {
2002                     /* Ignore illegal nopy */
2003                     if ((m & 7) == 0 && m != 0)
2004                       continue;
2005                     mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
2006                     expand_opcode (shift - 4, val | mv | (j << shift), i,
2007                                    s + 4);
2008                   }
2009             else if (s[2] == 'y')
2010               for (j = 0; j < 2; j++)
2011                 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2012             break;
2013           }
2014         case 'n':
2015         case 'm':
2016           for (j = 0; j < 16; j++)
2017             {
2018               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2019
2020             }
2021           break;
2022         case 'M':
2023           /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2024           for (j = 5; j < 16; j++)
2025             if (j != 6)
2026               expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2027           break;
2028         case 'G':
2029           /* A1G, A0G: */
2030           for (j = 13; j <= 15; j +=2)
2031             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2032           break;
2033         case 's':
2034           /* System registers mach, macl, pr: */
2035           for (j = 0; j < 3; j++)
2036             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2037           /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2038           for (j = 5; j < 12; j++)
2039             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2040           break;
2041         case 'X':
2042         case 'a':
2043           val |= bton (s) << shift;
2044           for (j = 0; j < 16; j += 8)
2045             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2046           break;
2047         case 'Y':
2048         case 'A':
2049           val |= bton (s) << shift;
2050           for (j = 0; j < 8; j += 4)
2051             expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2052           break;
2053
2054         default:
2055           for (j = 0; j < (1 << (shift + 4)); j++)
2056             {
2057               table[val | j] = i;
2058             }
2059         }
2060     }
2061 }
2062
2063 /* Print the jump table used to index an opcode into a switch
2064    statement entry. */
2065
2066 static void
2067 dumptable (name, size, start)
2068      char *name;
2069      int size;
2070      int start;
2071 {
2072   int lump = 256;
2073   int online = 16;
2074
2075   int i = start;
2076
2077   printf ("unsigned char %s[%d]={\n", name, size);
2078   while (i < start + size)
2079     {
2080       int j = 0;
2081
2082       printf ("/* 0x%x */\n", i);
2083
2084       while (j < lump)
2085         {
2086           int k = 0;
2087           while (k < online)
2088             {
2089               printf ("%2d", table[i + j + k]);
2090               if (j + k < lump)
2091                 printf (",");
2092
2093               k++;
2094             }
2095           j += k;
2096           printf ("\n");
2097         }
2098       i += j;
2099     }
2100   printf ("};\n");
2101 }
2102
2103
2104 static void
2105 filltable (p)
2106      op *p;
2107 {
2108   static int index = 1;
2109
2110   sorttab ();
2111   for (; p->name; p++)
2112     {
2113       p->index = index++;
2114       expand_opcode (12, 0, p->index, p->code);
2115     }
2116 }
2117
2118 /* Table already contais all the switch case tags for 16-bit opcode double
2119    data transfer (ddt) insns, and the switch case tag for processing parallel
2120    processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
2121    latter tag to represent all combinations of ppi with ddt.  */
2122 static void
2123 ppi_moves ()
2124 {
2125   int i;
2126
2127   for (i = 0xf000; i < 0xf400; i++)
2128     if (table[i])
2129       table[i + 0x800] = table[0xf800];
2130 }
2131
2132 static void
2133 gensim_caselist (p)
2134      op *p;
2135 {
2136   for (; p->name; p++)
2137     {
2138       int j;
2139       int sextbit = -1;
2140       int needm = 0;
2141       int needn = 0;
2142       
2143       char *s = p->code;
2144
2145       printf ("  /* %s %s */\n", p->name, p->code);
2146       printf ("  case %d:      \n", p->index);
2147
2148       printf ("    {\n");
2149       while (*s)
2150         {
2151           switch (*s)
2152             {
2153             case '0':
2154             case '1':
2155               s += 2;
2156               break;
2157             case '.':
2158               s += 4;
2159               break;
2160             case 'n':
2161               printf ("      int n = (iword >>8) & 0xf;\n");
2162               needn = 1;
2163               s += 4;
2164               break;
2165             case 'N':
2166               printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2167               s += 2;
2168               break;
2169             case 'x':
2170               printf ("      int n = ((iword >> 9) & 1) + 4;\n");
2171               needn = 1;
2172               s += 2;
2173               break;
2174             case 'y':
2175               printf ("      int n = ((iword >> 8) & 1) + 4;\n");
2176               needn = 1;
2177               s += 2;
2178               break;
2179             case 'm':
2180               needm = 1;
2181             case 's':
2182             case 'M':
2183             case 'G':
2184               printf ("      int m = (iword >>4) & 0xf;\n");
2185               s += 4;
2186               break;
2187             case 'X':
2188               printf ("      int m = ((iword >> 7) & 1) + 8;\n");
2189               s += 2;
2190               break;
2191             case 'a':
2192               printf ("      int m = 7 - ((iword >> 6) & 2);\n");
2193               s += 2;
2194               break;
2195             case 'Y':
2196               printf ("      int m = ((iword >> 6) & 1) + 10;\n");
2197               s += 2;
2198               break;
2199             case 'A':
2200               printf ("      int m = 7 - ((iword >> 5) & 2);\n");
2201               s += 2;
2202               break;
2203
2204             case 'i':
2205               printf ("      int i = (iword & 0x");
2206
2207               switch (s[1])
2208                 {
2209                 case '4':
2210                   printf ("f");
2211                   break;
2212                 case '8':
2213                   printf ("ff");
2214                   break;
2215                 case '1':
2216                   sextbit = 12;
2217
2218                   printf ("fff");
2219                   break;
2220                 }
2221               printf (")");
2222
2223               switch (s[3])
2224                 {
2225                 case '1':
2226                   break;
2227                 case '2':
2228                   printf ("<<1");
2229                   break;
2230                 case '4':
2231                   printf ("<<2");
2232                   break;
2233                 }
2234               printf (";\n");
2235               s += 4;
2236             }
2237         }
2238       if (sextbit > 0)
2239         {
2240           printf ("      i = (i ^ (1<<%d))-(1<<%d);\n",
2241                   sextbit - 1, sextbit - 1);
2242         }
2243
2244       if (needm && needn)
2245         printf ("      TB(m,n);\n");  
2246       else if (needm)
2247         printf ("      TL(m);\n");
2248       else if (needn)
2249         printf ("      TL(n);\n");
2250
2251       {
2252         /* Do the refs */
2253         char *r;
2254         for (r = p->refs; *r; r++)
2255           {
2256             if (*r == '0') printf("      CREF(0);\n"); 
2257             if (*r == '8') printf("      CREF(8);\n"); 
2258             if (*r == '9') printf("      CREF(9);\n"); 
2259             if (*r == 'n') printf("      CREF(n);\n"); 
2260             if (*r == 'm') printf("      CREF(m);\n"); 
2261           }
2262       }
2263
2264       printf ("      {\n");
2265       for (j = 0; j < MAX_NR_STUFF; j++)
2266         {
2267           if (p->stuff[j])
2268             {
2269               printf ("        %s\n", p->stuff[j]);
2270             }
2271         }
2272       printf ("      }\n");
2273
2274       {
2275         /* Do the defs */
2276         char *r;
2277         for (r = p->defs; *r; r++) 
2278           {
2279             if (*r == '0') printf("      CDEF(0);\n"); 
2280             if (*r == 'n') printf("      CDEF(n);\n"); 
2281             if (*r == 'm') printf("      CDEF(m);\n"); 
2282           }
2283       }
2284
2285       printf ("      break;\n");
2286       printf ("    }\n");
2287     }
2288 }
2289
2290 static void
2291 gensim ()
2292 {
2293   printf ("{\n");
2294   printf ("  switch (jump_table[iword]) {\n");
2295
2296   gensim_caselist (tab);
2297   gensim_caselist (movsxy_tab);
2298
2299   printf ("  default:\n");
2300   printf ("    {\n");
2301   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2302   printf ("    }\n");
2303   printf ("  }\n");
2304   printf ("}\n");
2305 }
2306
2307 static void
2308 gendefines ()
2309 {
2310   op *p;
2311   filltable (tab);
2312   for (p = tab; p->name; p++)
2313     {
2314       char *s = p->name;
2315       printf ("#define OPC_");
2316       while (*s) {
2317         if (isupper(*s)) 
2318           *s = tolower(*s);
2319         if (isalpha(*s)) printf("%c", *s);
2320         if (*s == ' ') printf("_");
2321         if (*s == '@') printf("ind_");
2322         if (*s == ',') printf("_");
2323         s++;
2324       }
2325       printf(" %d\n",p->index);
2326     }
2327 }
2328
2329 static int ppi_index;
2330
2331 /* Take an ppi code, expand all varying fields in it and fill all the
2332    right entries in 'table' with the opcode index.  */
2333
2334 static void
2335 expand_ppi_code (val, i, s)
2336      int val;
2337      int i;
2338      char *s;
2339 {
2340   int j;
2341
2342   for (;;)
2343     {
2344       switch (s[0])
2345         {
2346         /* The last eight bits are disregarded for the switch table.  */
2347         case 'm':
2348         case 'x':
2349         case '.':
2350           table[val] = i;
2351           return;
2352         case '0':
2353           val += val;
2354           s++;
2355           break;
2356         case '1':
2357           val += val + 1;
2358           s++;
2359           break;
2360         case 'i':
2361         case 'e': case 'f':
2362           val += val;
2363           s++;
2364           expand_ppi_code (val, i, s);
2365           val++;
2366           break;
2367         case 'c':
2368           val <<= 2;
2369           s += 2;
2370           val++;
2371           expand_ppi_code (val, ppi_index++, s);
2372           val++;
2373           expand_ppi_code (val, i, s);
2374           val++;
2375           break;
2376         }
2377     }
2378 }
2379
2380 static void
2381 ppi_filltable ()
2382 {
2383   op *p;
2384   ppi_index = 1;
2385
2386   for (p = ppi_tab; p->name; p++)
2387     {
2388       p->index = ppi_index++;
2389       expand_ppi_code (0, p->index, p->code);
2390     }
2391 }
2392
2393 static void
2394 ppi_gensim ()
2395 {
2396   op *p = ppi_tab;
2397
2398   printf ("#define DSR_MASK_G 0x80\n");
2399   printf ("#define DSR_MASK_Z 0x40\n");
2400   printf ("#define DSR_MASK_N 0x20\n");
2401   printf ("#define DSR_MASK_V 0x10\n");
2402   printf ("\n");
2403   printf ("#define COMPUTE_OVERFLOW do {\\\n");
2404   printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2405   printf ("  if (overflow && S) \\\n");
2406   printf ("    { \\\n");
2407   printf ("      if (res_grd & 0x80) \\\n");
2408   printf ("        { \\\n");
2409   printf ("          res = 0x80000000; \\\n");
2410   printf ("          res_grd |=  0xff; \\\n");
2411   printf ("        } \\\n");
2412   printf ("      else \\\n");
2413   printf ("        { \\\n");
2414   printf ("          res = 0x7fffffff; \\\n");
2415   printf ("          res_grd &= ~0xff; \\\n");
2416   printf ("        } \\\n");
2417   printf ("      overflow = 0; \\\n");
2418   printf ("    } \\\n");
2419   printf ("} while (0)\n");
2420   printf ("\n");
2421   printf ("#define ADD_SUB_GE \\\n");
2422   printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2423   printf ("\n");
2424   printf ("static void\n");
2425   printf ("ppi_insn (iword)\n");
2426   printf ("     int iword;\n");
2427   printf ("{\n");
2428   printf ("  static char e_tab[] = { 8,  9, 10,  5};\n");
2429   printf ("  static char f_tab[] = {10, 11,  8,  5};\n");
2430   printf ("  static char x_tab[] = { 8,  9,  7,  5};\n");
2431   printf ("  static char y_tab[] = {10, 11, 12, 14};\n");
2432   printf ("  static char g_tab[] = {12, 14,  7,  5};\n");
2433   printf ("  static char u_tab[] = { 8, 10,  7,  5};\n");
2434   printf ("\n");
2435   printf ("  int z;\n");
2436   printf ("  int res, res_grd;\n");
2437   printf ("  int carry, overflow, greater_equal;\n");
2438   printf ("\n");
2439   printf ("  switch (ppi_table[iword >> 8]) {\n");
2440
2441   for (; p->name; p++)
2442     {
2443       int shift, j;
2444       int cond = 0;
2445       int havedecl = 0;
2446       
2447       char *s = p->code;
2448
2449       printf ("  /* %s %s */\n", p->name, p->code);
2450       printf ("  case %d:      \n", p->index);
2451
2452       printf ("    {\n");
2453       for (shift = 16; *s; )
2454         {
2455           switch (*s)
2456             {
2457             case 'i':
2458               printf ("      int i = (iword >> 4) & 0x7f;\n");
2459               s += 6;
2460               break;
2461             case 'e':
2462             case 'f':
2463             case 'x':
2464             case 'y':
2465             case 'g':
2466             case 'u':
2467               shift -= 2;
2468               printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
2469                       *s, *s, shift);
2470               havedecl = 1;
2471               s += 2;
2472               break;
2473             case 'c':
2474               printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2475               printf ("\tbreak;\n");
2476               printf ("    }\n");
2477               printf ("  case %d:      \n", p->index + 1);
2478               printf ("    {\n");
2479               cond = 1;
2480             case '0':
2481             case '1':
2482             case '.':
2483               shift -= 2;
2484               s += 2;
2485               break;
2486             case 'z':
2487               if (havedecl)
2488                 printf ("\n");
2489               printf ("      z = iword & 0xf;\n");
2490               havedecl = 2;
2491               s += 4;
2492               break;
2493             }
2494         }
2495       if (havedecl == 1)
2496         printf ("\n");
2497       else if (havedecl == 2)
2498         printf ("      {\n");
2499       for (j = 0; j < MAX_NR_STUFF; j++)
2500         {
2501           if (p->stuff[j])
2502             {
2503               printf ("      %s%s\n",
2504                       (havedecl == 2 ? "  " : ""),
2505                       p->stuff[j]);
2506             }
2507         }
2508       if (havedecl == 2)
2509         printf ("      }\n");
2510       if (cond)
2511         {
2512           printf ("      if (iword & 0x200)\n");
2513           printf ("        goto assign_z;\n");
2514         }
2515       printf ("      break;\n");
2516       printf ("    }\n");
2517     }
2518
2519   printf ("  default:\n");
2520   printf ("    {\n");
2521   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2522   printf ("      return;\n");
2523   printf ("    }\n");
2524   printf ("  }\n");
2525   printf ("  DSR &= ~0xf1;\n");
2526   printf ("  if (res || res_grd)\n");
2527   printf ("    DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2528   printf ("  else\n");
2529   printf ("    DSR |= DSR_MASK_Z | overflow;\n");
2530   printf (" assign_dc:\n");
2531   printf ("  switch (DSR >> 1 & 7)\n");
2532   printf ("    {\n");
2533   printf ("    case 0: /* Carry Mode */\n");
2534   printf ("      DSR |= carry;\n");
2535   printf ("    case 1: /* Negative Value Mode */\n");
2536   printf ("      DSR |= res_grd >> 7 & 1;\n");
2537   printf ("    case 2: /* Zero Value Mode */\n");
2538   printf ("      DSR |= DSR >> 6 & 1;\n");
2539   printf ("    case 3: /* Overflow mode\n");
2540   printf ("      DSR |= overflow >> 4;\n");
2541   printf ("    case 4: /* Signed Greater Than Mode */\n");
2542   printf ("      DSR |= DSR >> 7 & 1;\n");
2543   printf ("    case 4: /* Signed Greater Than Or Equal Mode */\n");
2544   printf ("      DSR |= greater_equal >> 7;\n");
2545   printf ("    }\n");
2546   printf (" assign_z:\n");
2547   printf ("  if (0xa05f >> z & 1)\n");
2548   printf ("    {\n");
2549   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2550   printf ("      return;\n");
2551   printf ("    }\n");
2552   printf ("  DSP_R (z) = res;\n");
2553   printf ("  DSP_GRD (z) = res_grd;\n");
2554   printf ("}\n");
2555 }
2556
2557 int
2558 main (ac, av)
2559      int ac;
2560      char **av;
2561 {
2562   /* verify the table before anything else */
2563   {
2564     op *p;
2565     for (p = tab; p->name; p++)
2566       {
2567         /* check that the code field contains 16 bits */
2568         if (strlen (p->code) != 16)
2569           {
2570             fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2571                      p->code, strlen (p->code), p->name);
2572             abort ();
2573           }
2574       }
2575   }
2576
2577   /* now generate the requested data */
2578   if (ac > 1)
2579     {
2580       if (strcmp (av[1], "-t") == 0)
2581         {
2582           gengastab ();
2583         }
2584       else if (strcmp (av[1], "-d") == 0)
2585         {
2586           gendefines ();
2587         }
2588       else if (strcmp (av[1], "-s") == 0)
2589         {
2590           filltable (tab);
2591           dumptable ("sh_jump_table", 1 << 16, 0);
2592
2593           memset (table, 0, sizeof table);
2594           filltable (movsxy_tab);
2595           ppi_moves ();
2596           dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2597
2598           memset (table, 0, sizeof table);
2599           ppi_filltable ();
2600           dumptable ("ppi_table", 1 << 8, 0);
2601         }
2602       else if (strcmp (av[1], "-x") == 0)
2603         {
2604           filltable (tab);
2605           filltable (movsxy_tab);
2606           gensim ();
2607         }
2608       else if (strcmp (av[1], "-p") == 0)
2609         {
2610           ppi_filltable ();
2611           ppi_gensim ();
2612         }
2613     }
2614   else
2615     fprintf (stderr, "Opcode table generation no longer supported.\n");
2616   return 0;
2617 }