OSDN Git Service

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