26b461e818761810585f03d8f048c98d691eaf52
[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", "1111eeee11111101",
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 static unsigned char table[1 << 16];
1954
1955 /* Take an opcode, expand all varying fields in it out and fill all the
1956    right entries in 'table' with the opcode index.  */
1957
1958 static void
1959 expand_opcode (val, i, s)
1960      int val;
1961      int i;
1962      char *s;
1963 {
1964   if (*s == 0)
1965     {
1966       table[val] = i;
1967     }
1968   else
1969     {
1970       int j = 0, m = 0;
1971
1972       switch (s[0])
1973         {
1974         default:
1975           fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
1976           exit (1);
1977         case '0':
1978         case '1':
1979             /* Consume an arbitrary number of ones and zeros.  */
1980             do {
1981               j = (j << 1) + (s[m++] - '0');
1982             } while (s[m] == '0' || s[m] == '1');
1983             expand_opcode ((val << m) | j, i, s + m);
1984             break;
1985
1986         case 'N':       /* NN -- four-way fork */
1987           for (j = 0; j < 4; j++)
1988             expand_opcode ((val << 2) | j, i, s + 2);
1989           break;
1990         case 'x':       /* xx -- 2-way fork */
1991           /* Cross-breeding with movy moved to separate function.  */
1992           for (j = 0; j < 4; j += 2)
1993             expand_opcode ((val << 2) | j, i, s + 2);
1994           break;
1995         case 'y':       /* yy -- two-way fork */
1996           for (j = 0; j < 2; j++)
1997             expand_opcode ((val << 2) | j, i, s + 2);
1998           break;
1999         case 'i':       /* eg. "i8*1" */
2000         case '.':       /* "...." is a wildcard */
2001         case 'n':
2002         case 'm':
2003           /* nnnn, mmmm, i#*#, .... -- 16-way fork.  */
2004           for (j = 0; j < 16; j++)
2005             expand_opcode ((val << 4) | j, i, s + 4);
2006           break;
2007         case 'e':
2008           /* eeee -- even numbered register:
2009              8 way fork.  */
2010           for (j = 0; j < 15; j += 2)
2011             expand_opcode ((val << 4) | j, i, s + 4);
2012           break;
2013         case 'M':
2014           /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2015              MMMM -- 10-way fork */
2016           expand_opcode ((val << 4) | 5, i, s + 4);
2017           for (j = 7; j < 16; j++)
2018             expand_opcode ((val << 4) | j, i, s + 4);
2019           break;
2020         case 'G':
2021           /* A1G, A0G: 
2022              GGGG -- two-way fork */
2023           for (j = 13; j <= 15; j +=2)
2024             expand_opcode ((val << 4) | j, i, s + 4);
2025           break;
2026         case 's':
2027           /* ssss -- 10-way fork */
2028           /* System registers mach, macl, pr: */
2029           for (j = 0; j < 3; j++)
2030             expand_opcode ((val << 4) | j, i, s + 4);
2031           /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2032           for (j = 5; j < 12; j++)
2033             expand_opcode ((val << 4) | j, i, s + 4);
2034           break;
2035         case 'X':
2036         case 'a':
2037           /* XX, aa -- two-way fork */
2038           for (j = 0; j < 4; j += 2)
2039             expand_opcode ((val << 2) | j, i, s + 2);
2040           break;
2041         case 'Y':
2042         case 'A':
2043           /* YY, AA -- two-way fork */
2044           for (j = 0; j < 2; j++)
2045             expand_opcode ((val << 2) | j, i, s + 2);
2046           break;
2047         }
2048     }
2049 }
2050
2051 /* Print the jump table used to index an opcode into a switch
2052    statement entry. */
2053
2054 static void
2055 dumptable (name, size, start)
2056      char *name;
2057      int size;
2058      int start;
2059 {
2060   int lump = 256;
2061   int online = 16;
2062
2063   int i = start;
2064
2065   printf ("unsigned char %s[%d]={\n", name, size);
2066   while (i < start + size)
2067     {
2068       int j = 0;
2069
2070       printf ("/* 0x%x */\n", i);
2071
2072       while (j < lump)
2073         {
2074           int k = 0;
2075           while (k < online)
2076             {
2077               printf ("%2d", table[i + j + k]);
2078               if (j + k < lump)
2079                 printf (",");
2080
2081               k++;
2082             }
2083           j += k;
2084           printf ("\n");
2085         }
2086       i += j;
2087     }
2088   printf ("};\n");
2089 }
2090
2091
2092 static void
2093 filltable (p)
2094      op *p;
2095 {
2096   static int index = 1;
2097
2098   sorttab ();
2099   for (; p->name; p++)
2100     {
2101       p->index = index++;
2102       expand_opcode (0, p->index, p->code);
2103     }
2104 }
2105
2106 /* Table already contains all the switch case tags for 16-bit opcode double
2107    data transfer (ddt) insns, and the switch case tag for processing parallel
2108    processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
2109    latter tag to represent all combinations of ppi with ddt.  */
2110 static void
2111 expand_ppi_movxy ()
2112 {
2113   int i;
2114
2115   for (i = 0xf000; i < 0xf400; i++)
2116     if ((i & 3) == 0 && (i & 12) != 0 && table[i] != 0)
2117       {
2118         /* A movx insn, which needs to be filled out with the 
2119            corresponding movy insns.  This used to be done in
2120            expand_opcode.  */
2121         int m, mv;
2122
2123         for (m = 0; m < 32; m++)
2124           {
2125             /* Ignore illegal nopy */
2126             if ((m & 7) == 0 && m != 0)
2127               continue;
2128             mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
2129             table [i | mv] = table [i];
2130           }
2131       }
2132
2133   for (i = 0xf000; i < 0xf400; i++)
2134     if (table[i])
2135       table[i + 0x800] = table[0xf800];
2136 }
2137
2138 static void
2139 gensim_caselist (p)
2140      op *p;
2141 {
2142   for (; p->name; p++)
2143     {
2144       int j;
2145       int sextbit = -1;
2146       int needm = 0;
2147       int needn = 0;
2148       
2149       char *s = p->code;
2150
2151       printf ("  /* %s %s */\n", p->name, p->code);
2152       printf ("  case %d:      \n", p->index);
2153
2154       printf ("    {\n");
2155       while (*s)
2156         {
2157           switch (*s)
2158             {
2159             default:
2160               fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2161                        *s);
2162               exit (1);
2163               break;
2164             case '0':
2165             case '1':
2166               s += 2;
2167               break;
2168             case '.':
2169               s += 4;
2170               break;
2171             case 'n':
2172             case 'e':
2173               printf ("      int n = (iword >> 8) & 0xf;\n");
2174               needn = 1;
2175               s += 4;
2176               break;
2177             case 'N':
2178               printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2179               s += 2;
2180               break;
2181             case 'x':
2182               printf ("      int n = ((iword >> 9) & 1) + 4;\n");
2183               needn = 1;
2184               s += 2;
2185               break;
2186             case 'y':
2187               printf ("      int n = ((iword >> 8) & 1) + 6;\n");
2188               needn = 1;
2189               s += 2;
2190               break;
2191             case 'm':
2192               needm = 1;
2193             case 's':
2194             case 'M':
2195             case 'G':
2196               printf ("      int m = (iword >> 4) & 0xf;\n");
2197               s += 4;
2198               break;
2199             case 'X':
2200               printf ("      int m = ((iword >> 7) & 1) + 8;\n");
2201               s += 2;
2202               break;
2203             case 'a':
2204               printf ("      int m = 7 - ((iword >> 6) & 2);\n");
2205               s += 2;
2206               break;
2207             case 'Y':
2208               printf ("      int m = ((iword >> 6) & 1) + 10;\n");
2209               s += 2;
2210               break;
2211             case 'A':
2212               printf ("      int m = 7 - ((iword >> 5) & 2);\n");
2213               s += 2;
2214               break;
2215
2216             case 'i':
2217               printf ("      int i = (iword & 0x");
2218
2219               switch (s[1])
2220                 {
2221                 case '4':
2222                   printf ("f");
2223                   break;
2224                 case '8':
2225                   printf ("ff");
2226                   break;
2227                 case '1':
2228                   sextbit = 12;
2229
2230                   printf ("fff");
2231                   break;
2232                 }
2233               printf (")");
2234
2235               switch (s[3])
2236                 {
2237                 case '1':
2238                   break;
2239                 case '2':
2240                   printf ("<<1");
2241                   break;
2242                 case '4':
2243                   printf ("<<2");
2244                   break;
2245                 }
2246               printf (";\n");
2247               s += 4;
2248             }
2249         }
2250       if (sextbit > 0)
2251         {
2252           printf ("      i = (i ^ (1<<%d))-(1<<%d);\n",
2253                   sextbit - 1, sextbit - 1);
2254         }
2255
2256       if (needm && needn)
2257         printf ("      TB(m,n);\n");  
2258       else if (needm)
2259         printf ("      TL(m);\n");
2260       else if (needn)
2261         printf ("      TL(n);\n");
2262
2263       {
2264         /* Do the refs */
2265         char *r;
2266         for (r = p->refs; *r; r++)
2267           {
2268             if (*r == '0') printf("      CREF(0);\n"); 
2269             if (*r == '8') printf("      CREF(8);\n"); 
2270             if (*r == '9') printf("      CREF(9);\n"); 
2271             if (*r == 'n') printf("      CREF(n);\n"); 
2272             if (*r == 'm') printf("      CREF(m);\n"); 
2273           }
2274       }
2275
2276       printf ("      {\n");
2277       for (j = 0; j < MAX_NR_STUFF; j++)
2278         {
2279           if (p->stuff[j])
2280             {
2281               printf ("        %s\n", p->stuff[j]);
2282             }
2283         }
2284       printf ("      }\n");
2285
2286       {
2287         /* Do the defs */
2288         char *r;
2289         for (r = p->defs; *r; r++) 
2290           {
2291             if (*r == '0') printf("      CDEF(0);\n"); 
2292             if (*r == 'n') printf("      CDEF(n);\n"); 
2293             if (*r == 'm') printf("      CDEF(m);\n"); 
2294           }
2295       }
2296
2297       printf ("      break;\n");
2298       printf ("    }\n");
2299     }
2300 }
2301
2302 static void
2303 gensim ()
2304 {
2305   printf ("{\n");
2306   printf ("  switch (jump_table[iword]) {\n");
2307
2308   gensim_caselist (tab);
2309   gensim_caselist (movsxy_tab);
2310
2311   printf ("  default:\n");
2312   printf ("    {\n");
2313   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2314   printf ("    }\n");
2315   printf ("  }\n");
2316   printf ("}\n");
2317 }
2318
2319 static void
2320 gendefines ()
2321 {
2322   op *p;
2323   filltable (tab);
2324   for (p = tab; p->name; p++)
2325     {
2326       char *s = p->name;
2327       printf ("#define OPC_");
2328       while (*s) {
2329         if (isupper(*s)) 
2330           *s = tolower(*s);
2331         if (isalpha(*s)) printf("%c", *s);
2332         if (*s == ' ') printf("_");
2333         if (*s == '@') printf("ind_");
2334         if (*s == ',') printf("_");
2335         s++;
2336       }
2337       printf(" %d\n",p->index);
2338     }
2339 }
2340
2341 static int ppi_index;
2342
2343 /* Take a ppi code, expand all varying fields in it and fill all the
2344    right entries in 'table' with the opcode index.  */
2345
2346 static void
2347 expand_ppi_code (val, i, s)
2348      int val;
2349      int i;
2350      char *s;
2351 {
2352   int j;
2353
2354   for (;;)
2355     {
2356       switch (s[0])
2357         {
2358         default:
2359           fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n",
2360                    s[0]);
2361           exit (2);
2362           break;
2363         /* The last eight bits are disregarded for the switch table.  */
2364         case 'm':
2365         case 'x':
2366         case '.':
2367           table[val] = i;
2368           return;
2369         case '0':
2370           val += val;
2371           s++;
2372           break;
2373         case '1':
2374           val += val + 1;
2375           s++;
2376           break;
2377         case 'i':
2378         case 'e': case 'f':
2379           val += val;
2380           s++;
2381           expand_ppi_code (val, i, s);
2382           val++;
2383           break;
2384         case 'c':
2385           val <<= 2;
2386           s += 2;
2387           val++;
2388           expand_ppi_code (val, ppi_index++, s);
2389           val++;
2390           expand_ppi_code (val, i, s);
2391           val++;
2392           break;
2393         }
2394     }
2395 }
2396
2397 static void
2398 ppi_filltable ()
2399 {
2400   op *p;
2401   ppi_index = 1;
2402
2403   for (p = ppi_tab; p->name; p++)
2404     {
2405       p->index = ppi_index++;
2406       expand_ppi_code (0, p->index, p->code);
2407     }
2408 }
2409
2410 static void
2411 ppi_gensim ()
2412 {
2413   op *p = ppi_tab;
2414
2415   printf ("#define DSR_MASK_G 0x80\n");
2416   printf ("#define DSR_MASK_Z 0x40\n");
2417   printf ("#define DSR_MASK_N 0x20\n");
2418   printf ("#define DSR_MASK_V 0x10\n");
2419   printf ("\n");
2420   printf ("#define COMPUTE_OVERFLOW do {\\\n");
2421   printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2422   printf ("  if (overflow && S) \\\n");
2423   printf ("    { \\\n");
2424   printf ("      if (res_grd & 0x80) \\\n");
2425   printf ("        { \\\n");
2426   printf ("          res = 0x80000000; \\\n");
2427   printf ("          res_grd |=  0xff; \\\n");
2428   printf ("        } \\\n");
2429   printf ("      else \\\n");
2430   printf ("        { \\\n");
2431   printf ("          res = 0x7fffffff; \\\n");
2432   printf ("          res_grd &= ~0xff; \\\n");
2433   printf ("        } \\\n");
2434   printf ("      overflow = 0; \\\n");
2435   printf ("    } \\\n");
2436   printf ("} while (0)\n");
2437   printf ("\n");
2438   printf ("#define ADD_SUB_GE \\\n");
2439   printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2440   printf ("\n");
2441   printf ("static void\n");
2442   printf ("ppi_insn (iword)\n");
2443   printf ("     int iword;\n");
2444   printf ("{\n");
2445   printf ("  static char e_tab[] = { 8,  9, 10,  5};\n");
2446   printf ("  static char f_tab[] = {10, 11,  8,  5};\n");
2447   printf ("  static char x_tab[] = { 8,  9,  7,  5};\n");
2448   printf ("  static char y_tab[] = {10, 11, 12, 14};\n");
2449   printf ("  static char g_tab[] = {12, 14,  7,  5};\n");
2450   printf ("  static char u_tab[] = { 8, 10,  7,  5};\n");
2451   printf ("\n");
2452   printf ("  int z;\n");
2453   printf ("  int res, res_grd;\n");
2454   printf ("  int carry, overflow, greater_equal;\n");
2455   printf ("\n");
2456   printf ("  switch (ppi_table[iword >> 8]) {\n");
2457
2458   for (; p->name; p++)
2459     {
2460       int shift, j;
2461       int cond = 0;
2462       int havedecl = 0;
2463       
2464       char *s = p->code;
2465
2466       printf ("  /* %s %s */\n", p->name, p->code);
2467       printf ("  case %d:      \n", p->index);
2468
2469       printf ("    {\n");
2470       for (shift = 16; *s; )
2471         {
2472           switch (*s)
2473             {
2474             case 'i':
2475               printf ("      int i = (iword >> 4) & 0x7f;\n");
2476               s += 6;
2477               break;
2478             case 'e':
2479             case 'f':
2480             case 'x':
2481             case 'y':
2482             case 'g':
2483             case 'u':
2484               shift -= 2;
2485               printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
2486                       *s, *s, shift);
2487               havedecl = 1;
2488               s += 2;
2489               break;
2490             case 'c':
2491               printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2492               printf ("\treturn;\n");
2493               printf ("    }\n");
2494               printf ("  case %d:      \n", p->index + 1);
2495               printf ("    {\n");
2496               cond = 1;
2497             case '0':
2498             case '1':
2499             case '.':
2500               shift -= 2;
2501               s += 2;
2502               break;
2503             case 'z':
2504               if (havedecl)
2505                 printf ("\n");
2506               printf ("      z = iword & 0xf;\n");
2507               havedecl = 2;
2508               s += 4;
2509               break;
2510             }
2511         }
2512       if (havedecl == 1)
2513         printf ("\n");
2514       else if (havedecl == 2)
2515         printf ("      {\n");
2516       for (j = 0; j < MAX_NR_STUFF; j++)
2517         {
2518           if (p->stuff[j])
2519             {
2520               printf ("      %s%s\n",
2521                       (havedecl == 2 ? "  " : ""),
2522                       p->stuff[j]);
2523             }
2524         }
2525       if (havedecl == 2)
2526         printf ("      }\n");
2527       if (cond)
2528         {
2529           printf ("      if (iword & 0x200)\n");
2530           printf ("        goto assign_z;\n");
2531         }
2532       printf ("      break;\n");
2533       printf ("    }\n");
2534     }
2535
2536   printf ("  default:\n");
2537   printf ("    {\n");
2538   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2539   printf ("      return;\n");
2540   printf ("    }\n");
2541   printf ("  }\n");
2542   printf ("  DSR &= ~0xf1;\n");
2543   printf ("  if (res || res_grd)\n");
2544   printf ("    DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2545   printf ("  else\n");
2546   printf ("    DSR |= DSR_MASK_Z | overflow;\n");
2547   printf (" assign_dc:\n");
2548   printf ("  switch (DSR >> 1 & 7)\n");
2549   printf ("    {\n");
2550   printf ("    case 0: /* Carry Mode */\n");
2551   printf ("      DSR |= carry;\n");
2552   printf ("    case 1: /* Negative Value Mode */\n");
2553   printf ("      DSR |= res_grd >> 7 & 1;\n");
2554   printf ("    case 2: /* Zero Value Mode */\n");
2555   printf ("      DSR |= DSR >> 6 & 1;\n");
2556   printf ("    case 3: /* Overflow mode\n");
2557   printf ("      DSR |= overflow >> 4;\n");
2558   printf ("    case 4: /* Signed Greater Than Mode */\n");
2559   printf ("      DSR |= DSR >> 7 & 1;\n");
2560   printf ("    case 4: /* Signed Greater Than Or Equal Mode */\n");
2561   printf ("      DSR |= greater_equal >> 7;\n");
2562   printf ("    }\n");
2563   printf (" assign_z:\n");
2564   printf ("  if (0xa05f >> z & 1)\n");
2565   printf ("    {\n");
2566   printf ("      RAISE_EXCEPTION (SIGILL);\n");
2567   printf ("      return;\n");
2568   printf ("    }\n");
2569   printf ("  DSP_R (z) = res;\n");
2570   printf ("  DSP_GRD (z) = res_grd;\n");
2571   printf ("}\n");
2572 }
2573
2574 int
2575 main (ac, av)
2576      int ac;
2577      char **av;
2578 {
2579   /* verify the table before anything else */
2580   {
2581     op *p;
2582     for (p = tab; p->name; p++)
2583       {
2584         /* check that the code field contains 16 bits */
2585         if (strlen (p->code) != 16)
2586           {
2587             fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2588                      p->code, strlen (p->code), p->name);
2589             abort ();
2590           }
2591       }
2592   }
2593
2594   /* now generate the requested data */
2595   if (ac > 1)
2596     {
2597       if (strcmp (av[1], "-t") == 0)
2598         {
2599           gengastab ();
2600         }
2601       else if (strcmp (av[1], "-d") == 0)
2602         {
2603           gendefines ();
2604         }
2605       else if (strcmp (av[1], "-s") == 0)
2606         {
2607           filltable (tab);
2608           dumptable ("sh_jump_table", 1 << 16, 0);
2609
2610           memset (table, 0, sizeof table);
2611           filltable (movsxy_tab);
2612           expand_ppi_movxy ();
2613           dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2614
2615           memset (table, 0, sizeof table);
2616           ppi_filltable ();
2617           dumptable ("ppi_table", 1 << 8, 0);
2618         }
2619       else if (strcmp (av[1], "-x") == 0)
2620         {
2621           filltable (tab);
2622           filltable (movsxy_tab);
2623           gensim ();
2624         }
2625       else if (strcmp (av[1], "-p") == 0)
2626         {
2627           ppi_filltable ();
2628           ppi_gensim ();
2629         }
2630     }
2631   else
2632     fprintf (stderr, "Opcode table generation no longer supported.\n");
2633   return 0;
2634 }