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