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