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