xref: /netbsd-src/external/gpl3/gdb/dist/sim/sh/gencode.c (revision 4d1eaf9104083d3c1d72a17f5c414777b18c6935)
1 /* Simulator/Opcode generator for the Renesas
2    (formerly Hitachi) / SuperH Inc. Super-H architecture.
3 
4    Written by Steve Chamberlain of Cygnus Support.
5    sac@cygnus.com
6 
7    This file is part of SH sim.
8 
9 
10 		THIS SOFTWARE IS NOT COPYRIGHTED
11 
12    Cygnus offers the following for use in the public domain.  Cygnus
13    makes no warranty with regard to the software or it's performance
14    and the user accepts the software "AS IS" with all faults.
15 
16    CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
17    THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 
20 */
21 
22 /* This program generates the opcode table for the assembler and
23    the simulator code.
24 
25    -t		prints a pretty table for the assembler manual
26    -s		generates the simulator code jump table
27    -d		generates a define table
28    -x		generates the simulator code switch statement
29    default 	used to generate the opcode tables
30 
31 */
32 
33 #include <ctype.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include "libiberty.h"
39 
40 #define MAX_NR_STUFF 42
41 
42 typedef struct
43 {
44   const char * const defs;
45   const char * const refs;
46   const char * const name;
47   const char * const code;
48   const char * const stuff[MAX_NR_STUFF];
49   int index;
50 } op;
51 
52 
53 static op tab[] =
54 {
55 
56   { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
57     {
58       "R[n] += SEXT (i);",
59       "if (i == 0) {",
60       "  UNDEF(n); /* see #ifdef PARANOID */",
61       "  break;",
62       "}",
63     },
64   },
65   { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
66     {
67       "R[n] += R[m];",
68     },
69   },
70 
71   { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
72     {
73       "ult = R[n] + T;",
74       "SET_SR_T (ult < R[n]);",
75       "R[n] = ult + R[m];",
76       "SET_SR_T (T || (R[n] < ult));",
77     },
78   },
79 
80   { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
81     {
82       "ult = R[n] + R[m];",
83       "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
84       "R[n] = ult;",
85     },
86   },
87 
88   { "0", "0", "and #<imm>,R0", "11001001i8*1....",
89     {
90       "R0 &= i;",
91     },
92   },
93   { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
94     {
95       "R[n] &= R[m];",
96     },
97   },
98   { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
99     {
100       "MA (1);",
101       "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
102     },
103   },
104 
105   { "", "", "bf <bdisp8>", "10001011i8p1....",
106     {
107       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
108       "if (!T) {",
109       "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
110       "  cycles += 2;",
111       "}",
112     },
113   },
114 
115   { "", "", "bf.s <bdisp8>", "10001111i8p1....",
116     {
117       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
118       "if (!T) {",
119       "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
120       "  cycles += 2;",
121       "  Delay_Slot (PC + 2);",
122       "}",
123     },
124   },
125 
126   { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
127     {
128       "/* 32-bit logical bit-manipulation instructions.  */",
129       "int word2 = RIAT (nip);",
130       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
131       "i >>= 4;	/* BOGUS: Using only three bits of 'i'.  */",
132       "/* MSB of 'i' must be zero.  */",
133       "if (i > 7)",
134       "  RAISE_EXCEPTION (SIGILL);",
135       "MA (1);",
136       "do_blog_insn (1 << i, (word2 & 0xfff) + R[n],",
137       "              (word2 >> 12) & 0xf, memory, maskb);",
138       "SET_NIP (nip + 2);	/* Consume 2 more bytes.  */",
139     },
140   },
141   { "", "", "bra <bdisp12>", "1010i12.........",
142     {
143       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
144       "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
145       "cycles += 2;",
146       "Delay_Slot (PC + 2);",
147     },
148   },
149 
150   { "", "n", "braf <REG_N>", "0000nnnn00100011",
151     {
152       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
153       "SET_NIP (PC + 4 + R[n]);",
154       "cycles += 2;",
155       "Delay_Slot (PC + 2);",
156     },
157   },
158 
159   { "", "", "bsr <bdisp12>", "1011i12.........",
160     {
161       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
162       "PR = PH2T (PC + 4);",
163       "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
164       "cycles += 2;",
165       "Delay_Slot (PC + 2);",
166     },
167   },
168 
169   { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
170     {
171       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
172       "PR = PH2T (PC) + 4;",
173       "SET_NIP (PC + 4 + R[n]);",
174       "cycles += 2;",
175       "Delay_Slot (PC + 2);",
176     },
177   },
178 
179   { "", "", "bt <bdisp8>", "10001001i8p1....",
180     {
181       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
182       "if (T) {",
183       "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
184       "  cycles += 2;",
185       "}",
186     },
187   },
188 
189   { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
190     {
191       "/* MSB of 'i' is true for load, false for store.  */",
192       "if (i <= 7)",
193       "  if (T)",
194       "    R[m] |= (1 << i);",
195       "  else",
196       "    R[m] &= ~(1 << i);",
197       "else",
198       "  SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
199     },
200   },
201   { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
202     {
203       "/* MSB of 'i' is true for set, false for clear.  */",
204       "if (i <= 7)",
205       "  R[m] &= ~(1 << i);",
206       "else",
207       "  R[m] |= (1 << (i - 8));",
208     },
209   },
210   { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
211     {
212       "if (R[n] < -128 || R[n] > 127) {",
213       "  L (n);",
214       "  SET_SR_CS (1);",
215       "  if (R[n] > 127)",
216       "    R[n] = 127;",
217       "  else if (R[n] < -128)",
218       "    R[n] = -128;",
219       "}",
220     },
221   },
222   { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
223     {
224       "if (R[n] < -32768 || R[n] > 32767) {",
225       "  L (n);",
226       "  SET_SR_CS (1);",
227       "  if (R[n] > 32767)",
228       "    R[n] = 32767;",
229       "  else if (R[n] < -32768)",
230       "    R[n] = -32768;",
231       "}",
232     },
233   },
234   { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
235     {
236       "if (R[n] < -256 || R[n] > 255) {",
237       "  L (n);",
238       "  SET_SR_CS (1);",
239       "  R[n] = 255;",
240       "}",
241     },
242   },
243   { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
244     {
245       "if (R[n] < -65536 || R[n] > 65535) {",
246       "  L (n);",
247       "  SET_SR_CS (1);",
248       "  R[n] = 65535;",
249       "}",
250     },
251   },
252   { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
253     {
254       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
255       "if (R0 == 0)",
256       "  R[n] = 0x7fffffff;",
257       "else if (R0 == -1 && R[n] == 0x80000000)",
258       "  R[n] = 0x7fffffff;",
259       "else R[n] /= R0;",
260       "L (n);",
261     },
262   },
263   { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
264     {
265       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
266       "if (R0 == 0)",
267       "  R[n] = 0xffffffff;",
268       "/* FIXME: The result may be implementation-defined if it is outside */",
269       "/* the range of signed int (i.e. if R[n] was negative and R0 == 1).  */",
270       "else R[n] = R[n] / (unsigned int) R0;",
271       "L (n);",
272     },
273   },
274   { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
275     {
276       "R[n] = (R[n] * R0) & 0xffffffff;",
277       "L (n);",
278     },
279   },
280   { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
281     {
282       "int regn = (R[n] >> 2) & 0x1f;",
283       "int bankn = (R[n] >> 7) & 0x1ff;",
284       "if (regn > 19)",
285       "  regn = 19;	/* FIXME what should happen? */",
286       "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
287       "L (0);",
288     },
289   },
290   { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
291     {
292       "int regn = (R[n] >> 2) & 0x1f;",
293       "int bankn = (R[n] >> 7) & 0x1ff;",
294       "if (regn > 19)",
295       "  regn = 19;	/* FIXME what should happen? */",
296       "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
297     },
298   },
299   { "", "", "resbank", "0000000001011011",
300     {
301       "int i;",
302       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
303       /* FIXME: cdef all */
304       "if (BO) {	/* Bank Overflow */",
305       /* FIXME: how do we know when to reset BO?  */
306       "  for (i = 0; i <= 14; i++) {",
307       "    R[i] = RLAT (R[15]);",
308       "    MA (1);",
309       "    R[15] += 4;",
310       "  }",
311       "  PR = RLAT (R[15]);",
312       "  R[15] += 4;",
313       "  MA (1);",
314       "  GBR = RLAT (R[15]);",
315       "  R[15] += 4;",
316       "  MA (1);",
317       "  MACH = RLAT (R[15]);",
318       "  R[15] += 4;",
319       "  MA (1);",
320       "  MACL = RLAT (R[15]);",
321       "  R[15] += 4;",
322       "  MA (1);",
323       "}",
324       "else if (BANKN == 0)	/* Bank Underflow */",
325       "  RAISE_EXCEPTION (SIGILL);",	/* FIXME: what exception? */
326       "else {",
327       "  SET_BANKN (BANKN - 1);",
328       "  for (i = 0; i <= 14; i++)",
329       "    R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
330       "  MACH = saved_state.asregs.regstack[BANKN].regs[15];",
331       "  PR   = saved_state.asregs.regstack[BANKN].regs[17];",
332       "  GBR  = saved_state.asregs.regstack[BANKN].regs[18];",
333       "  MACL = saved_state.asregs.regstack[BANKN].regs[19];",
334       "}",
335     },
336   },
337   { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
338     {
339       "/* Push Rn...R0 (if n==15, push pr and R14...R0).  */",
340       "do {",
341       "  MA (1);",
342       "  R[15] -= 4;",
343       "  if (n == 15)",
344       "    WLAT (R[15], PR);",
345       "  else",
346       "    WLAT (R[15], R[n]);",
347       "} while (n-- > 0);",
348     },
349   },
350   { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
351     {
352       "/* Pop R0...Rn (if n==15, pop R0...R14 and pr).  */",
353       "int i = 0;\n",
354       "do {",
355       "  MA (1);",
356       "  if (i == 15)",
357       "    PR = RLAT (R[15]);",
358       "  else",
359       "    R[i] = RLAT (R[15]);",
360       "  R[15] += 4;",
361       "} while (i++ < n);",
362     },
363   },
364   { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
365     {
366       "/* Push pr, R14...Rn (if n==15, push pr).  */",	/* FIXME */
367       "int i = 15;\n",
368       "do {",
369       "  MA (1);",
370       "  R[15] -= 4;",
371       "  if (i == 15)",
372       "    WLAT (R[15], PR);",
373       "  else",
374       "    WLAT (R[15], R[i]);",
375       "} while (i-- > n);",
376     },
377   },
378   { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
379     {
380       "/* Pop Rn...R14, pr (if n==15, pop pr).  */",	/* FIXME */
381       "do {",
382       "  MA (1);",
383       "  if (n == 15)",
384       "    PR = RLAT (R[15]);",
385       "  else",
386       "    R[n] = RLAT (R[15]);",
387       "  R[15] += 4;",
388       "} while (n++ < 15);",
389     },
390   },
391   { "", "", "nott", "0000000001101000",
392     {
393       "SET_SR_T (T == 0);",
394     },
395   },
396 
397   { "", "", "bt.s <bdisp8>", "10001101i8p1....",
398     {
399       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
400       "if (T) {",
401       "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
402       "  cycles += 2;",
403       "  Delay_Slot (PC + 2);",
404       "}",
405     },
406   },
407 
408   { "", "", "clrmac", "0000000000101000",
409     {
410       "MACH = 0;",
411       "MACL = 0;",
412     },
413   },
414 
415   { "", "", "clrs", "0000000001001000",
416     {
417       "SET_SR_S (0);",
418     },
419   },
420 
421   { "", "", "clrt", "0000000000001000",
422     {
423       "SET_SR_T (0);",
424     },
425   },
426 
427   /* sh4a */
428   { "", "", "clrdmxy", "0000000010001000",
429     {
430       "saved_state.asregs.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
431     },
432   },
433 
434   { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
435     {
436       "SET_SR_T (R0 == SEXT (i));",
437     },
438   },
439   { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
440     {
441       "SET_SR_T (R[n] == R[m]);",
442     },
443   },
444   { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
445     {
446       "SET_SR_T (R[n] >= R[m]);",
447     },
448   },
449   { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
450     {
451       "SET_SR_T (R[n] > R[m]);",
452     },
453   },
454   { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
455     {
456       "SET_SR_T (UR[n] > UR[m]);",
457     },
458   },
459   { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
460     {
461       "SET_SR_T (UR[n] >= UR[m]);",
462     },
463   },
464   { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
465     {
466       "SET_SR_T (R[n] > 0);",
467     },
468   },
469   { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
470     {
471       "SET_SR_T (R[n] >= 0);",
472     },
473   },
474   { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
475     {
476       "ult = R[n] ^ R[m];",
477       "SET_SR_T (((ult & 0xff000000) == 0)",
478       "          | ((ult & 0xff0000) == 0)",
479       "          | ((ult & 0xff00) == 0)",
480       "          | ((ult & 0xff) == 0));",
481     },
482   },
483 
484   { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
485     {
486       "SET_SR_Q ((R[n] & sbit) != 0);",
487       "SET_SR_M ((R[m] & sbit) != 0);",
488       "SET_SR_T (M != Q);",
489     },
490   },
491 
492   { "", "", "div0u", "0000000000011001",
493     {
494       "SET_SR_M (0);",
495       "SET_SR_Q (0);",
496       "SET_SR_T (0);",
497     },
498   },
499 
500   { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
501     {
502       "div1 (&R0, m, n/*, T*/);",
503     },
504   },
505 
506   { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
507     {
508       "dmul_s (R[n], R[m]);",
509     },
510   },
511 
512   { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
513     {
514       "dmul_u (R[n], R[m]);",
515     },
516   },
517 
518   { "n", "n", "dt <REG_N>", "0100nnnn00010000",
519     {
520       "R[n]--;",
521       "SET_SR_T (R[n] == 0);",
522     },
523   },
524 
525   { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
526     {
527       "R[n] = SEXT (R[m]);",
528     },
529   },
530   { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
531     {
532       "R[n] = SEXTW (R[m]);",
533     },
534   },
535 
536   { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
537     {
538       "R[n] = (R[m] & 0xff);",
539     },
540   },
541   { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
542     {
543       "R[n] = (R[m] & 0xffff);",
544     },
545   },
546 
547   /* sh2e */
548   { "", "", "fabs <FREG_N>", "1111nnnn01011101",
549     {
550       "  union",
551       "  {",
552       "    unsigned int i;",
553       "    float f;",
554       "  } u;",
555       "  u.f = FR (n);",
556       "  u.i &= 0x7fffffff;",
557       "  SET_FR (n, u.f);",
558     },
559   },
560 
561   /* sh2e */
562   { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
563     {
564       "FP_OP (n, +, m);",
565     },
566   },
567 
568   /* sh2e */
569   { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
570     {
571       "FP_CMP (n, ==, m);",
572     },
573   },
574   /* sh2e */
575   { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
576     {
577       "FP_CMP (n, >, m);",
578     },
579   },
580 
581   /* sh4 */
582   { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
583     {
584       "if (! FPSCR_PR || n & 1)",
585       "  RAISE_EXCEPTION (SIGILL);",
586       "else",
587       "{",
588       "  union",
589       "  {",
590       "    int i;",
591       "    float f;",
592       "  } u;",
593       "  u.f = DR (n);",
594       "  FPUL = u.i;",
595       "}",
596     },
597   },
598 
599   /* sh4 */
600   { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
601     {
602       "if (! FPSCR_PR || n & 1)",
603       "  RAISE_EXCEPTION (SIGILL);",
604       "else",
605       "{",
606       "  union",
607       "  {",
608       "    int i;",
609       "    float f;",
610       "  } u;",
611       "  u.i = FPUL;",
612       "  SET_DR (n, u.f);",
613       "}",
614     },
615   },
616 
617   /* sh2e */
618   { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
619     {
620       "FP_OP (n, /, m);",
621       "/* FIXME: check for DP and (n & 1) == 0?  */",
622     },
623   },
624 
625   /* sh4 */
626   { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
627     {
628       "if (FPSCR_PR)",
629       "  RAISE_EXCEPTION (SIGILL);",
630       "else",
631       "{",
632       "  double fsum = 0;",
633       "  if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
634       "    RAISE_EXCEPTION (SIGILL);",
635       "  /* FIXME: check for nans and infinities.  */",
636       "  fsum += FR (v1+0) * FR (v2+0);",
637       "  fsum += FR (v1+1) * FR (v2+1);",
638       "  fsum += FR (v1+2) * FR (v2+2);",
639       "  fsum += FR (v1+3) * FR (v2+3);",
640       "  SET_FR (v1+3, fsum);",
641       "}",
642     },
643   },
644 
645   /* sh2e */
646   { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
647     {
648       "SET_FR (n, (float) 0.0);",
649       "/* FIXME: check for DP and (n & 1) == 0?  */",
650     },
651   },
652 
653   /* sh2e */
654   { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
655     {
656       "SET_FR (n, (float) 1.0);",
657       "/* FIXME: check for DP and (n & 1) == 0?  */",
658     },
659   },
660 
661   /* sh2e */
662   { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
663     {
664       "  union",
665       "  {",
666       "    int i;",
667       "    float f;",
668       "  } u;",
669       "  u.f = FR (n);",
670       "  FPUL = u.i;",
671     },
672   },
673 
674   /* sh2e */
675   { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
676     {
677       /* sh4 */
678       "if (FPSCR_PR)",
679       "  SET_DR (n, (double) FPUL);",
680       "else",
681       "{",
682       "  SET_FR (n, (float) FPUL);",
683       "}",
684     },
685   },
686 
687   /* sh2e */
688   { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
689     {
690       "SET_FR (n, FR (m) * FR (0) + FR (n));",
691       "/* FIXME: check for DP and (n & 1) == 0? */",
692     },
693   },
694 
695   /* sh2e */
696   { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
697     {
698       /* sh4 */
699       "if (FPSCR_SZ) {",
700       "  int ni = XD_TO_XF (n);",
701       "  int mi = XD_TO_XF (m);",
702       "  SET_XF (ni + 0, XF (mi + 0));",
703       "  SET_XF (ni + 1, XF (mi + 1));",
704       "}",
705       "else",
706       "{",
707       "  SET_FR (n, FR (m));",
708       "}",
709     },
710   },
711   /* sh2e */
712   { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
713     {
714       /* sh4 */
715       "if (FPSCR_SZ) {",
716       "  MA (2);",
717       "  WDAT (R[n], m);",
718       "}",
719       "else",
720       "{",
721       "  MA (1);",
722       "  WLAT (R[n], FI (m));",
723       "}",
724     },
725   },
726   /* sh2e */
727   { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
728     {
729       /* sh4 */
730       "if (FPSCR_SZ) {",
731       "  MA (2);",
732       "  RDAT (R[m], n);",
733       "}",
734       "else",
735       "{",
736       "  MA (1);",
737       "  SET_FI (n, RLAT (R[m]));",
738       "}",
739     },
740   },
741   /* sh2a */
742   { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
743     {
744       "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
745       "   and mov.bwl <REG_N>, @(disp12,<REG_M>)",
746       "   and mov.bwl @(disp12,<REG_N>),<REG_M>",
747       "   and movu.bw @(disp12,<REG_N>),<REG_M>.  */",
748       "int word2 = RIAT (nip);",
749       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
750       "SET_NIP (nip + 2);	/* Consume 2 more bytes.  */",
751       "MA (1);",
752       "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
753     },
754   },
755   /* sh2e */
756   { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
757     {
758       /* sh4 */
759       "if (FPSCR_SZ) {",
760       "  MA (2);",
761       "  RDAT (R[m], n);",
762       "  R[m] += 8;",
763       "}",
764       "else",
765       "{",
766       "  MA (1);",
767       "  SET_FI (n, RLAT (R[m]));",
768       "  R[m] += 4;",
769       "}",
770     },
771   },
772   /* sh2e */
773   { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
774     {
775       /* sh4 */
776       "if (FPSCR_SZ) {",
777       "  MA (2);",
778       "  R[n] -= 8;",
779       "  WDAT (R[n], m);",
780       "}",
781       "else",
782       "{",
783       "  MA (1);",
784       "  R[n] -= 4;",
785       "  WLAT (R[n], FI (m));",
786       "}",
787     },
788   },
789   /* sh2e */
790   { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
791     {
792       /* sh4 */
793       "if (FPSCR_SZ) {",
794       "  MA (2);",
795       "  RDAT (R[0]+R[m], n);",
796       "}",
797       "else",
798       "{",
799       "  MA (1);",
800       "  SET_FI (n, RLAT (R[0] + R[m]));",
801       "}",
802     },
803   },
804   /* sh2e */
805   { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
806     {
807       /* sh4 */
808       "if (FPSCR_SZ) {",
809       "  MA (2);",
810       "  WDAT (R[0]+R[n], m);",
811       "}",
812       "else",
813       "{",
814       "  MA (1);",
815       "  WLAT ((R[0]+R[n]), FI (m));",
816       "}",
817     },
818   },
819 
820   /* sh4:
821      See fmov instructions above for move to/from extended fp registers.  */
822 
823   /* sh2e */
824   { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
825     {
826       "FP_OP (n, *, m);",
827     },
828   },
829 
830   /* sh2e */
831   { "", "", "fneg <FREG_N>", "1111nnnn01001101",
832     {
833       "  union",
834       "  {",
835       "    unsigned int i;",
836       "    float f;",
837       "  } u;",
838       "  u.f = FR (n);",
839       "  u.i ^= 0x80000000;",
840       "  SET_FR (n, u.f);",
841     },
842   },
843 
844   /* sh4a */
845   { "", "", "fpchg", "1111011111111101",
846     {
847       "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
848     },
849   },
850 
851   /* sh4 */
852   { "", "", "frchg", "1111101111111101",
853     {
854       "if (FPSCR_PR)",
855       "  RAISE_EXCEPTION (SIGILL);",
856       "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
857       "  RAISE_EXCEPTION (SIGILL);",
858       "else",
859       "  SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
860     },
861   },
862 
863   /* sh4 */
864   { "", "", "fsca", "1111eeee11111101",
865     {
866       "if (FPSCR_PR)",
867       "  RAISE_EXCEPTION (SIGILL);",
868       "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
869       "  RAISE_EXCEPTION (SIGILL);",
870       "else",
871       "  {",
872       "    SET_FR (n, fsca_s (FPUL, &sin));",
873       "    SET_FR (n+1, fsca_s (FPUL, &cos));",
874       "  }",
875     },
876   },
877 
878   /* sh4 */
879   { "", "", "fschg", "1111001111111101",
880     {
881       "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
882     },
883   },
884 
885   /* sh3e */
886   { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
887     {
888       "FP_UNARY (n, sqrt);",
889     },
890   },
891 
892   /* sh4 */
893   { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
894     {
895       "if (FPSCR_PR)",
896       "  RAISE_EXCEPTION (SIGILL);",
897       "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
898       "  RAISE_EXCEPTION (SIGILL);",
899       "else",
900       "  SET_FR (n, fsrra_s (FR (n)));",
901     },
902   },
903 
904   /* sh2e */
905   { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
906     {
907       "FP_OP (n, -, m);",
908     },
909   },
910 
911   /* sh2e */
912   { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
913     {
914       /* sh4 */
915       "if (FPSCR_PR) {",
916       "  if (DR (n) != DR (n)) /* NaN */",
917       "    FPUL = 0x80000000;",
918       "  else",
919       "    FPUL =  (int) DR (n);",
920       "}",
921       "else",
922       "if (FR (n) != FR (n)) /* NaN */",
923       "  FPUL = 0x80000000;",
924       "else",
925       "  FPUL = (int) FR (n);",
926     },
927   },
928 
929   /* sh4 */
930   { "", "", "ftrv <FV_N>", "1111vv0111111101",
931     {
932       "if (FPSCR_PR)",
933       "  RAISE_EXCEPTION (SIGILL);",
934       "else",
935       "{",
936       "  if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
937       "    RAISE_EXCEPTION (SIGILL);",
938       "  /* FIXME not implemented.  */",
939       "  printf (\"ftrv xmtrx, FV%d\\n\", v1);",
940       "}",
941     },
942   },
943 
944   /* sh2e */
945   { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
946     {
947       "  union",
948       "  {",
949       "    int i;",
950       "    float f;",
951       "  } u;",
952       "  u.i = FPUL;",
953       "  SET_FR (n, u.f);",
954     },
955   },
956 
957   { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
958     {
959       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
960       "SET_NIP (PT2H (R[n]));",
961       "cycles += 2;",
962       "Delay_Slot (PC + 2);",
963     },
964   },
965 
966   { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
967     {
968       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
969       "PR = PH2T (PC + 4);",
970       "if (~doprofile)",
971       "  gotcall (PR, R[n]);",
972       "SET_NIP (PT2H (R[n]));",
973       "cycles += 2;",
974       "Delay_Slot (PC + 2);",
975     },
976   },
977   { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
978     {
979       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
980       "PR = PH2T (PC + 2);",
981       "if (~doprofile)",
982       "  gotcall (PR, R[n]);",
983       "SET_NIP (PT2H (R[n]));",
984     },
985   },
986   { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
987     {
988       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
989       "PR = PH2T (PC + 2);",
990       "if (~doprofile)",
991       "  gotcall (PR, i + TBR);",
992       "SET_NIP (PT2H (i + TBR));",
993     },
994   },
995 
996   { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
997     {
998       "CREG (m) = R[n];",
999       "/* FIXME: user mode */",
1000     },
1001   },
1002   { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
1003     {
1004       "SET_SR (R[n]);",
1005       "/* FIXME: user mode */",
1006     },
1007   },
1008   { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
1009     {
1010       "SET_MOD (R[n]);",
1011     },
1012   },
1013   { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
1014     {
1015       "if (SR_MD)",
1016       "  DBR = R[n]; /* priv mode */",
1017       "else",
1018       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1019     },
1020   },
1021   { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
1022     {
1023       "if (SR_MD)",
1024       "  SGR = R[n]; /* priv mode */",
1025       "else",
1026       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1027     },
1028   },
1029   { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
1030     {
1031       "if (SR_MD)",	/* FIXME? */
1032       "  TBR = R[n]; /* priv mode */",
1033       "else",
1034       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1035     },
1036   },
1037   { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
1038     {
1039       "MA (1);",
1040       "CREG (m) = RLAT (R[n]);",
1041       "R[n] += 4;",
1042       "/* FIXME: user mode */",
1043     },
1044   },
1045   { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
1046     {
1047       "MA (1);",
1048       "SET_SR (RLAT (R[n]));",
1049       "R[n] += 4;",
1050       "/* FIXME: user mode */",
1051     },
1052   },
1053   { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
1054     {
1055       "MA (1);",
1056       "SET_MOD (RLAT (R[n]));",
1057       "R[n] += 4;",
1058     },
1059   },
1060   { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
1061     {
1062       "if (SR_MD)",
1063       "{ /* priv mode */",
1064       "  MA (1);",
1065       "  DBR = RLAT (R[n]);",
1066       "  R[n] += 4;",
1067       "}",
1068       "else",
1069       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1070     },
1071   },
1072   { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
1073     {
1074       "if (SR_MD)",
1075       "{ /* priv mode */",
1076       "  MA (1);",
1077       "  SGR = RLAT (R[n]);",
1078       "  R[n] += 4;",
1079       "}",
1080       "else",
1081       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1082     },
1083   },
1084 
1085   /* sh-dsp */
1086   { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
1087     {
1088       "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
1089     },
1090   },
1091   { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
1092     {
1093       "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
1094     },
1095   },
1096 
1097   /* sh4a */
1098   { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
1099     {
1100       "SET_RC (R[n]);",
1101       "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
1102       "CHECK_INSN_PTR (insn_ptr);",
1103       "RE |= 1;",
1104     },
1105   },
1106   { "", "", "ldrc #<imm>", "10001010i8*1....",
1107     {
1108       "SET_RC (i);",
1109       "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
1110       "CHECK_INSN_PTR (insn_ptr);",
1111       "RE |= 1;",
1112     },
1113   },
1114 
1115   { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
1116     {
1117       "SREG (m) = R[n];",
1118     },
1119   },
1120   { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
1121     {
1122       "MA (1);",
1123       "SREG (m) = RLAT (R[n]);",
1124       "R[n] += 4;",
1125     },
1126   },
1127   /* sh2e / sh-dsp (lds <REG_N>,DSR) */
1128   { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
1129     {
1130       "SET_FPSCR (R[n]);",
1131     },
1132   },
1133   /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
1134   { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
1135     {
1136       "MA (1);",
1137       "SET_FPSCR (RLAT (R[n]));",
1138       "R[n] += 4;",
1139     },
1140   },
1141 
1142   { "", "", "ldtlb", "0000000000111000",
1143     {
1144       "/* We don't implement cache or tlb, so this is a noop.  */",
1145     },
1146   },
1147 
1148   { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
1149     {
1150       "macl (&R0, memory, n, m);",
1151     },
1152   },
1153 
1154   { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
1155     {
1156       "macw (&R0, memory, n, m, endianw);",
1157     },
1158   },
1159 
1160   { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
1161     {
1162       "R[n] = SEXT (i);",
1163     },
1164   },
1165   { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
1166     {
1167       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1168       "R[n] = ((i << 24) >> 12) | RIAT (nip);",
1169       "SET_NIP (nip + 2);	/* Consume 2 more bytes.  */",
1170     },
1171   },
1172   { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
1173     {
1174       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1175       "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
1176       "SET_NIP (nip + 2);	/* Consume 2 more bytes.  */",
1177     },
1178   },
1179   { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
1180     {
1181       "R[n] = R[m];",
1182     },
1183   },
1184 
1185   { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
1186     {
1187       "MA (1);",
1188       "R0 = RSBAT (i + GBR);",
1189       "L (0);",
1190     },
1191   },
1192   { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
1193     {
1194       "MA (1);",
1195       "R0 = RSBAT (i + R[m]);",
1196       "L (0);",
1197     },
1198   },
1199   { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
1200     {
1201       "MA (1);",
1202       "R[n] = RSBAT (R0 + R[m]);",
1203       "L (n);",
1204     },
1205   },
1206   { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
1207     {
1208       "MA (1);",
1209       "R[n] = RSBAT (R[m]);",
1210       "R[m] += 1;",
1211       "L (n);",
1212     },
1213   },
1214   { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
1215     {
1216       "MA (1);",
1217       "R[n] -= 1;",
1218       "R0 = RSBAT (R[n]);",
1219       "L (0);",
1220     },
1221   },
1222   { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
1223     {
1224       "MA (1);",
1225       "WBAT (R[n], R[m]);",
1226     },
1227   },
1228   { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
1229     {
1230       "MA (1);",
1231       "WBAT (i + GBR, R0);",
1232     },
1233   },
1234   { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
1235     {
1236       "MA (1);",
1237       "WBAT (i + R[m], R0);",
1238     },
1239   },
1240   { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
1241     {
1242       "MA (1);",
1243       "WBAT (R[n] + R0, R[m]);",
1244     },
1245   },
1246   { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
1247     {
1248       /* Allow for the case where m == n.  */
1249       "int t = R[m];",
1250       "MA (1);",
1251       "R[n] -= 1;",
1252       "WBAT (R[n], t);",
1253     },
1254   },
1255   { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
1256     {
1257       "MA (1);",
1258       "WBAT (R[n], R0);",
1259       "R[n] += 1;",
1260     },
1261   },
1262   { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
1263     {
1264       "MA (1);",
1265       "R[n] = RSBAT (R[m]);",
1266       "L (n);",
1267     },
1268   },
1269 
1270   { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
1271     {
1272       "MA (1);",
1273       "R0 = RLAT (i + GBR);",
1274       "L (0);",
1275     },
1276   },
1277   { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
1278     {
1279       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1280       "MA (1);",
1281       "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
1282       "L (n);",
1283     },
1284   },
1285   { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1286     {
1287       "MA (1);",
1288       "R[n] = RLAT (i + R[m]);",
1289       "L (n);",
1290     },
1291   },
1292   { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1293     {
1294       "MA (1);",
1295       "R[n] = RLAT (R0 + R[m]);",
1296       "L (n);",
1297     },
1298   },
1299   { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1300     {
1301       "MA (1);",
1302       "R[n] = RLAT (R[m]);",
1303       "R[m] += 4;",
1304       "L (n);",
1305     },
1306   },
1307   { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1308     {
1309       "MA (1);",
1310       "R[n] -= 4;",
1311       "R0 = RLAT (R[n]);",
1312       "L (0);",
1313     },
1314   },
1315   { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1316     {
1317       "MA (1);",
1318       "R[n] = RLAT (R[m]);",
1319       "L (n);",
1320     },
1321   },
1322   { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1323     {
1324       "MA (1);",
1325       "WLAT (i + GBR, R0);",
1326     },
1327   },
1328   { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1329     {
1330       "MA (1);",
1331       "WLAT (i + R[n], R[m]);",
1332     },
1333   },
1334   { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1335     {
1336       "MA (1);",
1337       "WLAT (R0 + R[n], R[m]);",
1338     },
1339   },
1340   { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1341     {
1342       /* Allow for the case where m == n.  */
1343       "int t = R[m];",
1344       "MA (1) ;",
1345       "R[n] -= 4;",
1346       "WLAT (R[n], t);",
1347     },
1348   },
1349   { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1350     {
1351       "MA (1) ;",
1352       "WLAT (R[n], R0);",
1353       "R[n] += 4;",
1354     },
1355   },
1356   { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1357     {
1358       "MA (1);",
1359       "WLAT (R[n], R[m]);",
1360     },
1361   },
1362 
1363   { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1364     {
1365       "MA (1);",
1366       "R0 = RSWAT (i + GBR);",
1367       "L (0);",
1368     },
1369   },
1370   { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1371     {
1372       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1373       "MA (1);",
1374       "R[n] = RSWAT (PH2T (PC + 4 + i));",
1375       "L (n);",
1376     },
1377   },
1378   { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1379     {
1380       "MA (1);",
1381       "R0 = RSWAT (i + R[m]);",
1382       "L (0);",
1383     },
1384   },
1385   { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1386     {
1387       "MA (1);",
1388       "R[n] = RSWAT (R0 + R[m]);",
1389       "L (n);",
1390     },
1391   },
1392   { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1393     {
1394       "MA (1);",
1395       "R[n] = RSWAT (R[m]);",
1396       "R[m] += 2;",
1397       "L (n);",
1398     },
1399   },
1400   { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1401     {
1402       "MA (1);",
1403       "R[n] -= 2;",
1404       "R0 = RSWAT (R[n]);",
1405       "L (0);",
1406     },
1407   },
1408   { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1409     {
1410       "MA (1);",
1411       "R[n] = RSWAT (R[m]);",
1412       "L (n);",
1413     },
1414   },
1415   { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1416     {
1417       "MA (1);",
1418       "WWAT (i + GBR, R0);",
1419     },
1420   },
1421   { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1422     {
1423       "MA (1);",
1424       "WWAT (i + R[m], R0);",
1425     },
1426   },
1427   { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1428     {
1429       "MA (1);",
1430       "WWAT (R0 + R[n], R[m]);",
1431     },
1432   },
1433   { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1434     {
1435       /* Allow for the case where m == n.  */
1436       "int t = R[m];",
1437       "MA (1);",
1438       "R[n] -= 2;",
1439       "WWAT (R[n], t);",
1440     },
1441   },
1442   { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1443     {
1444       "MA (1);",
1445       "WWAT (R[n], R0);",
1446       "R[n] += 2;",
1447     },
1448   },
1449   { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1450     {
1451       "MA (1);",
1452       "WWAT (R[n], R[m]);",
1453     },
1454   },
1455 
1456   { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1457     {
1458       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1459       "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1460     },
1461   },
1462 
1463   { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1464     {
1465       "/* We don't simulate cache, so this insn is identical to mov.  */",
1466       "MA (1);",
1467       "WLAT (R[n], R[0]);",
1468     },
1469   },
1470 
1471   { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1472     {
1473       "/* LDST -> T */",
1474       "SET_SR_T (LDST);",
1475       "/* if (T) R0 -> (Rn) */",
1476       "if (T)",
1477       "  WLAT (R[n], R[0]);",
1478       "/* 0 -> LDST */",
1479       "SET_LDST (0);",
1480     },
1481   },
1482 
1483   { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1484     {
1485       "/* 1 -> LDST */",
1486       "SET_LDST (1);",
1487       "/* (Rn) -> R0 */",
1488       "R[0] = RLAT (R[n]);",
1489       "/* if (interrupt/exception) 0 -> LDST */",
1490       "/* (we don't simulate asynchronous interrupts/exceptions) */",
1491     },
1492   },
1493 
1494   { "n", "", "movt <REG_N>", "0000nnnn00101001",
1495     {
1496       "R[n] = T;",
1497     },
1498   },
1499   { "", "", "movrt <REG_N>", "0000nnnn00111001",
1500     {
1501       "R[n] = (T == 0);",
1502     },
1503   },
1504   { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1505     {
1506       "int regn = R[n];",
1507       "int e = target_little_endian ? 3 : 0;",
1508       "MA (1);",
1509       "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) +",
1510       "  (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1511       "L (0);",
1512     },
1513   },
1514   { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1515     {
1516       "int regn = R[n];",
1517       "int e = target_little_endian ? 3 : 0;",
1518       "MA (1);",
1519       "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) +",
1520       "  (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1521       "R[n] += 4;",
1522       "L (0);",
1523     },
1524   },
1525   { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1526     {
1527       "MACL = ((int) R[n]) * ((int) R[m]);",
1528     },
1529   },
1530 #if 0  /* FIXME: The above cast to int is not really portable.
1531 	  It should be replaced by a SEXT32 macro.  */
1532   { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1533     {
1534       "MACL = R[n] * R[m];",
1535     },
1536   },
1537 #endif
1538 
1539   /* muls.w - see muls */
1540   { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1541     {
1542       "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1543     },
1544   },
1545 
1546   /* mulu.w - see mulu */
1547   { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1548     {
1549       "MACL = (((unsigned int) (unsigned short) R[n])",
1550       "        * ((unsigned int) (unsigned short) R[m]));",
1551     },
1552   },
1553 
1554   { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1555     {
1556       "R[n] = - R[m];",
1557     },
1558   },
1559 
1560   { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1561     {
1562       "ult = -T;",
1563       "SET_SR_T (ult > 0);",
1564       "R[n] = ult - R[m];",
1565       "SET_SR_T (T || (R[n] > ult));",
1566     },
1567   },
1568 
1569   { "", "", "nop", "0000000000001001",
1570     {
1571       "/* nop */",
1572     },
1573   },
1574 
1575   { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1576     {
1577       "R[n] = ~R[m];",
1578     },
1579   },
1580 
1581   /* sh4a */
1582   { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1583     {
1584       "/* Except for the effect on the cache - which is not simulated -",
1585       "   this is like a nop.  */",
1586     },
1587   },
1588 
1589   { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1590     {
1591       "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop.  */",
1592       "/* FIXME: Cache not implemented */",
1593     },
1594   },
1595 
1596   { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1597     {
1598       "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop.  */",
1599       "/* FIXME: Cache not implemented */",
1600     },
1601   },
1602 
1603   { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1604     {
1605       "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop.  */",
1606       "/* FIXME: Cache not implemented */",
1607     },
1608   },
1609 
1610   { "0", "", "or #<imm>,R0", "11001011i8*1....",
1611     {
1612       "R0 |= i;",
1613     },
1614   },
1615   { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1616     {
1617       "R[n] |= R[m];",
1618     },
1619   },
1620   { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1621     {
1622       "MA (1);",
1623       "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1624     },
1625   },
1626 
1627   { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1628     {
1629       "/* Except for the effect on the cache - which is not simulated -",
1630       "   this is like a nop.  */",
1631     },
1632   },
1633 
1634   /* sh4a */
1635   { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1636     {
1637       "/* Except for the effect on the cache - which is not simulated -",
1638       "   this is like a nop.  */",
1639     },
1640   },
1641 
1642   /* sh4a */
1643   { "", "", "synco", "0000000010101011",
1644     {
1645       "/* Except for the effect on the pipeline - which is not simulated -",
1646       "   this is like a nop.  */",
1647     },
1648   },
1649 
1650   { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1651     {
1652       "ult = R[n] < 0;",
1653       "R[n] = (R[n] << 1) | T;",
1654       "SET_SR_T (ult);",
1655     },
1656   },
1657 
1658   { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1659     {
1660       "ult = R[n] & 1;",
1661       "R[n] = (UR[n] >> 1) | (T << 31);",
1662       "SET_SR_T (ult);",
1663     },
1664   },
1665 
1666   { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1667     {
1668       "SET_SR_T (R[n] < 0);",
1669       "R[n] <<= 1;",
1670       "R[n] |= T;",
1671     },
1672   },
1673 
1674   { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1675     {
1676       "SET_SR_T (R[n] & 1);",
1677       "R[n] = UR[n] >> 1;",
1678       "R[n] |= (T << 31);",
1679     },
1680   },
1681 
1682   { "", "", "rte", "0000000000101011",
1683     {
1684 #if 0
1685       /* SH-[12] */
1686       "int tmp = PC;",
1687       "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1688       "R[15] += 4;",
1689       "SET_SR (RLAT (R[15]) & 0x3f3);",
1690       "R[15] += 4;",
1691       "Delay_Slot (PC + 2);",
1692 #else
1693       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1694       "SET_SR (SSR);",
1695       "SET_NIP (PT2H (SPC));",
1696       "cycles += 2;",
1697       "Delay_Slot (PC + 2);",
1698 #endif
1699     },
1700   },
1701 
1702   { "", "", "rts", "0000000000001011",
1703     {
1704       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1705       "SET_NIP (PT2H (PR));",
1706       "cycles += 2;",
1707       "Delay_Slot (PC + 2);",
1708     },
1709   },
1710   { "", "", "rts/n", "0000000001101011",
1711     {
1712       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1713       "SET_NIP (PT2H (PR));",
1714     },
1715   },
1716   { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1717     {
1718       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1719       "R0 = R[n];",
1720       "L (0);",
1721       "SET_NIP (PT2H (PR));",
1722     },
1723   },
1724 
1725   /* sh4a */
1726   { "", "", "setdmx", "0000000010011000",
1727     {
1728       "saved_state.asregs.sr |=  SR_MASK_DMX;"
1729       "saved_state.asregs.sr &= ~SR_MASK_DMY;"
1730     },
1731   },
1732 
1733   /* sh4a */
1734   { "", "", "setdmy", "0000000011001000",
1735     {
1736       "saved_state.asregs.sr |=  SR_MASK_DMY;"
1737       "saved_state.asregs.sr &= ~SR_MASK_DMX;"
1738     },
1739   },
1740 
1741   /* sh-dsp */
1742   { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1743     {
1744       "SET_RC (R[n]);",
1745     },
1746   },
1747   { "", "", "setrc #<imm>", "10000010i8*1....",
1748     {
1749       /* It would be more realistic to let loop_start point to some static
1750 	 memory that contains an illegal opcode and then give a bus error when
1751 	 the loop is eventually encountered, but it seems not only simpler,
1752 	 but also more debugging-friendly to just catch the failure here.  */
1753       "if (BUSERROR (RS | RE, maskw))",
1754       "  RAISE_EXCEPTION (SIGILL);",
1755       "else {",
1756       "  SET_RC (i);",
1757       "  loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1758       "  CHECK_INSN_PTR (insn_ptr);",
1759       "}",
1760     },
1761   },
1762 
1763   { "", "", "sets", "0000000001011000",
1764     {
1765       "SET_SR_S (1);",
1766     },
1767   },
1768 
1769   { "", "", "sett", "0000000000011000",
1770     {
1771       "SET_SR_T (1);",
1772     },
1773   },
1774 
1775   { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1776     {
1777       "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1778     },
1779   },
1780 
1781   { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1782     {
1783       "SET_SR_T (R[n] < 0);",
1784       "R[n] <<= 1;",
1785     },
1786   },
1787 
1788   { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1789     {
1790       "SET_SR_T (R[n] & 1);",
1791       "R[n] = R[n] >> 1;",
1792     },
1793   },
1794 
1795   { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1796     {
1797       "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1798     },
1799   },
1800 
1801   { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1802     {
1803       "SET_SR_T (R[n] < 0);",
1804       "R[n] <<= 1;",
1805     },
1806   },
1807 
1808   { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1809     {
1810       "R[n] <<= 2;",
1811     },
1812   },
1813   { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1814     {
1815       "R[n] <<= 8;",
1816     },
1817   },
1818   { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1819     {
1820       "R[n] <<= 16;",
1821     },
1822   },
1823 
1824   { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1825     {
1826       "SET_SR_T (R[n] & 1);",
1827       "R[n] = UR[n] >> 1;",
1828     },
1829   },
1830 
1831   { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1832     {
1833       "R[n] = UR[n] >> 2;",
1834     },
1835   },
1836   { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1837     {
1838       "R[n] = UR[n] >> 8;",
1839     },
1840   },
1841   { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1842     {
1843       "R[n] = UR[n] >> 16;",
1844     },
1845   },
1846 
1847   { "", "", "sleep", "0000000000011011",
1848     {
1849       "nip += trap (sd, 0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1850     },
1851   },
1852 
1853   { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1854     {
1855       "R[n] = CREG (m);",
1856     },
1857   },
1858 
1859   { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1860     {
1861       "if (SR_MD)",
1862       "  R[n] = SGR; /* priv mode */",
1863       "else",
1864       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1865     },
1866   },
1867   { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1868     {
1869       "if (SR_MD)",
1870       "  R[n] = DBR; /* priv mode */",
1871       "else",
1872       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1873     },
1874   },
1875   { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1876     {
1877       "if (SR_MD)",	/* FIXME? */
1878       "  R[n] = TBR; /* priv mode */",
1879       "else",
1880       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1881     },
1882   },
1883   { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1884     {
1885       "MA (1);",
1886       "R[n] -= 4;",
1887       "WLAT (R[n], CREG (m));",
1888     },
1889   },
1890   { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1891     {
1892       "if (SR_MD)",
1893       "{ /* priv mode */",
1894       "  MA (1);",
1895       "  R[n] -= 4;",
1896       "  WLAT (R[n], SGR);",
1897       "}",
1898       "else",
1899       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1900     },
1901   },
1902   { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1903     {
1904       "if (SR_MD)",
1905       "{ /* priv mode */",
1906       "  MA (1);",
1907       "  R[n] -= 4;",
1908       "  WLAT (R[n], DBR);",
1909       "}",
1910       "else",
1911       "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1912     },
1913   },
1914 
1915   { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1916     {
1917       "R[n] = SREG (m);",
1918     },
1919   },
1920   { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1921     {
1922       "MA (1);",
1923       "R[n] -= 4;",
1924       "WLAT (R[n], SREG (m));",
1925     },
1926   },
1927 
1928   { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1929     {
1930       "R[n] -= R[m];",
1931     },
1932   },
1933 
1934   { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1935     {
1936       "ult = R[n] - T;",
1937       "SET_SR_T (ult > R[n]);",
1938       "R[n] = ult - R[m];",
1939       "SET_SR_T (T || (R[n] > ult));",
1940     },
1941   },
1942 
1943   { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1944     {
1945       "ult = R[n] - R[m];",
1946       "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1947       "R[n] = ult;",
1948     },
1949   },
1950 
1951   { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1952     {
1953       "R[n] = ((R[m] & 0xffff0000)",
1954       "        | ((R[m] << 8) & 0xff00)",
1955       "        | ((R[m] >> 8) & 0x00ff));",
1956     },
1957   },
1958   { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1959     {
1960       "R[n] = (((R[m] << 16) & 0xffff0000)",
1961       "        | ((R[m] >> 16) & 0x00ffff));",
1962     },
1963   },
1964 
1965   { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1966     {
1967       "MA (1);",
1968       "ult = RBAT (R[n]);",
1969       "SET_SR_T (ult == 0);",
1970       "WBAT (R[n],ult|0x80);",
1971     },
1972   },
1973 
1974   { "0", "", "trapa #<imm>", "11000011i8*1....",
1975     {
1976       "long imm = 0xff & i;",
1977       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1978       "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1979       "  nip += trap (sd, i, &R0, PC, memory, maskl, maskw, endianw);",
1980 #if 0
1981       "else {",
1982       /* SH-[12] */
1983       "  R[15] -= 4;",
1984       "  WLAT (R[15], GET_SR ());",
1985       "  R[15] -= 4;",
1986       "  WLAT (R[15], PH2T (PC + 2));",
1987 #else
1988       "else if (!SR_BL) {",
1989       "  SSR = GET_SR ();",
1990       "  SPC = PH2T (PC + 2);",
1991       "  SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1992       "  /* FIXME: EXPEVT = 0x00000160; */",
1993 #endif
1994       "  SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1995       "}",
1996     },
1997   },
1998 
1999   { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
2000     {
2001       "SET_SR_T ((R[n] & R[m]) == 0);",
2002     },
2003   },
2004   { "", "0", "tst #<imm>,R0", "11001000i8*1....",
2005     {
2006       "SET_SR_T ((R0 & i) == 0);",
2007     },
2008   },
2009   { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
2010     {
2011       "MA (1);",
2012       "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
2013     },
2014   },
2015 
2016   { "", "0", "xor #<imm>,R0", "11001010i8*1....",
2017     {
2018       "R0 ^= i;",
2019     },
2020   },
2021   { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
2022     {
2023       "R[n] ^= R[m];",
2024     },
2025   },
2026   { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
2027     {
2028       "MA (1);",
2029       "ult = RBAT (GBR+R0);",
2030       "ult ^= i;",
2031       "WBAT (GBR + R0, ult);",
2032     },
2033   },
2034 
2035   { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
2036     {
2037       "R[n] = (((R[n] >> 16) & 0xffff)",
2038       "        | ((R[m] << 16) & 0xffff0000));",
2039     },
2040   },
2041 
2042 #if 0
2043   { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
2044     {
2045       "divl (0, R[n], R[m]);",
2046     },
2047   },
2048   { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
2049     {
2050       "divl (0, R[n], R[m]);",
2051     },
2052   },
2053 #endif
2054 
2055   {},
2056 };
2057 
2058 static op movsxy_tab[] =
2059 {
2060 /* If this is disabled, the simulator speeds up by about 12% on a
2061    450 MHz PIII - 9% with ACE_FAST.
2062    Maybe we should have separate simulator loops?  */
2063 #if 1
2064   { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
2065     {
2066       "MA (1);",
2067       "R[n] -= 2;",
2068       "DSP_R (m) = RSWAT (R[n]) << 16;",
2069       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2070     },
2071   },
2072   { "", "n",  "movs.w @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0100",
2073     {
2074       "MA (1);",
2075       "DSP_R (m) = RSWAT (R[n]) << 16;",
2076       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2077     },
2078   },
2079   { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
2080     {
2081       "MA (1);",
2082       "DSP_R (m) = RSWAT (R[n]) << 16;",
2083       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2084       "R[n] += 2;",
2085     },
2086   },
2087   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
2088     {
2089       "MA (1);",
2090       "DSP_R (m) = RSWAT (R[n]) << 16;",
2091       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2092       "R[n] += R[8];",
2093     },
2094   },
2095   { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
2096     {
2097       "MA (1);",
2098       "R[n] -= 2;",
2099       "DSP_R (m) = RSWAT (R[n]);",
2100     },
2101   },
2102   { "", "n",  "movs.w @<REG_N>,<DSP_GRD_M>",  "111101NNGGGG0100",
2103     {
2104       "MA (1);",
2105       "DSP_R (m) = RSWAT (R[n]);",
2106     },
2107   },
2108   { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
2109     {
2110       "MA (1);",
2111       "DSP_R (m) = RSWAT (R[n]);",
2112       "R[n] += 2;",
2113     },
2114   },
2115   { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
2116     {
2117       "MA (1);",
2118       "DSP_R (m) = RSWAT (R[n]);",
2119       "R[n] += R[8];",
2120     },
2121   },
2122   { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
2123     {
2124       "MA (1);",
2125       "R[n] -= 2;",
2126       "WWAT (R[n], DSP_R (m) >> 16);",
2127     },
2128   },
2129   { "", "n",  "movs.w <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0101",
2130     {
2131       "MA (1);",
2132       "WWAT (R[n], DSP_R (m) >> 16);",
2133     },
2134   },
2135   { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
2136     {
2137       "MA (1);",
2138       "WWAT (R[n], DSP_R (m) >> 16);",
2139       "R[n] += 2;",
2140     },
2141   },
2142   { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
2143     {
2144       "MA (1);",
2145       "WWAT (R[n], DSP_R (m) >> 16);",
2146       "R[n] += R[8];",
2147     },
2148   },
2149   { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
2150     {
2151       "MA (1);",
2152       "R[n] -= 2;",
2153       "WWAT (R[n], SEXT (DSP_R (m)));",
2154     },
2155   },
2156   { "", "n",  "movs.w <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0101",
2157     {
2158       "MA (1);",
2159       "WWAT (R[n], SEXT (DSP_R (m)));",
2160     },
2161   },
2162   { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
2163     {
2164       "MA (1);",
2165       "WWAT (R[n], SEXT (DSP_R (m)));",
2166       "R[n] += 2;",
2167     },
2168   },
2169   { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
2170     {
2171       "MA (1);",
2172       "WWAT (R[n], SEXT (DSP_R (m)));",
2173       "R[n] += R[8];",
2174     },
2175   },
2176   { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
2177     {
2178       "MA (1);",
2179       "R[n] -= 4;",
2180       "DSP_R (m) = RLAT (R[n]);",
2181       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2182     },
2183   },
2184   { "", "n",  "movs.l @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0110",
2185     {
2186       "MA (1);",
2187       "DSP_R (m) = RLAT (R[n]);",
2188       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2189     },
2190   },
2191   { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
2192     {
2193       "MA (1);",
2194       "DSP_R (m) = RLAT (R[n]);",
2195       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2196       "R[n] += 4;",
2197     },
2198   },
2199   { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
2200     {
2201       "MA (1);",
2202       "DSP_R (m) = RLAT (R[n]);",
2203       "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2204       "R[n] += R[8];",
2205     },
2206   },
2207   { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
2208     {
2209       "MA (1);",
2210       "R[n] -= 4;",
2211       "WLAT (R[n], DSP_R (m));",
2212     },
2213   },
2214   { "", "n",  "movs.l <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0111",
2215     {
2216       "MA (1);",
2217       "WLAT (R[n], DSP_R (m));",
2218     },
2219   },
2220   { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
2221     {
2222       "MA (1);",
2223       "WLAT (R[n], DSP_R (m));",
2224       "R[n] += 4;",
2225     },
2226   },
2227   { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
2228     {
2229       "MA (1);",
2230       "WLAT (R[n], DSP_R (m));",
2231       "R[n] += R[8];",
2232     },
2233   },
2234   { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
2235     {
2236       "MA (1);",
2237       "R[n] -= 4;",
2238       "WLAT (R[n], SEXT (DSP_R (m)));",
2239     },
2240   },
2241   { "", "n",  "movs.l <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0111",
2242     {
2243       "MA (1);",
2244       "WLAT (R[n], SEXT (DSP_R (m)));",
2245     },
2246   },
2247   { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
2248     {
2249       "MA (1);",
2250       "WLAT (R[n], SEXT (DSP_R (m)));",
2251       "R[n] += 4;",
2252     },
2253   },
2254   { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
2255     {
2256       "MA (1);",
2257       "WLAT (R[n], SEXT (DSP_R (m)));",
2258       "R[n] += R[8];",
2259     },
2260   },
2261   { "", "n", "movx.w @<REG_xy>,<DSP_XY>",   "111100xyXY0001??",
2262     {
2263       "DSP_R (m) = RSWAT (R[n]) << 16;",
2264       "if (iword & 3)",
2265       "  {",
2266       "    iword &= 0xfd53; goto top;",
2267       "  }",
2268     },
2269   },
2270   { "", "n", "movx.l @<REG_xy>,<DSP_XY>",   "111100xyXY010100",
2271     {
2272       "DSP_R (m) = RLAT (R[n]);",
2273     },
2274   },
2275   { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
2276     {
2277       "DSP_R (m) = RSWAT (R[n]) << 16;",
2278       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2279       "if (iword & 3)",
2280       "  {",
2281       "    iword &= 0xfd53; goto top;",
2282       "  }",
2283     },
2284   },
2285   { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
2286     {
2287       "DSP_R (m) = RLAT (R[n]);",
2288       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2289     },
2290   },
2291   { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
2292     {
2293       "DSP_R (m) = RSWAT (R[n]) << 16;",
2294       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2295       "if (iword & 3)",
2296       "  {",
2297       "    iword &= 0xfd53; goto top;",
2298       "  }",
2299     },
2300   },
2301   { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
2302     {
2303       "DSP_R (m) = RLAT (R[n]);",
2304       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2305     },
2306   },
2307   { "", "n", "movx.w <DSP_Ax>,@<REG_xy>",   "111100xyax1001??",
2308     {
2309       "WWAT (R[n], DSP_R (m) >> 16);",
2310       "if (iword & 3)",
2311       "  {",
2312       "    iword &= 0xfd53; goto top;",
2313       "  }",
2314     },
2315   },
2316   { "", "n", "movx.l <DSP_Ax>,@<REG_xy>",   "111100xyax110100",
2317     {
2318       "WLAT (R[n], DSP_R (m));",
2319     },
2320   },
2321   { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
2322     {
2323       "WWAT (R[n], DSP_R (m) >> 16);",
2324       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2325       "if (iword & 3)",
2326       "  {",
2327       "    iword &= 0xfd53; goto top;",
2328       "  }",
2329     },
2330   },
2331   { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
2332     {
2333       "WLAT (R[n], DSP_R (m));",
2334       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2335     },
2336   },
2337   { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
2338     {
2339       "WWAT (R[n], DSP_R (m) >> 16);",
2340       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2341       "if (iword & 3)",
2342       "  {",
2343       "    iword &= 0xfd53; goto top;",
2344       "  }",
2345     },
2346   },
2347   { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
2348     {
2349       "WLAT (R[n], DSP_R (m));",
2350       "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2351     },
2352   },
2353   { "", "n", "movy.w @<REG_yx>,<DSP_YX>",   "111100yxYX000001",
2354     {
2355       "DSP_R (m) = RSWAT (R[n]) << 16;",
2356     },
2357   },
2358   { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
2359     {
2360       "DSP_R (m) = RSWAT (R[n]) << 16;",
2361       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2362     },
2363   },
2364   { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
2365     {
2366       "DSP_R (m) = RSWAT (R[n]) << 16;",
2367       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2368     },
2369   },
2370   { "", "n", "movy.w <DSP_Ay>,@<REG_yx>",   "111100yxAY010001",
2371     {
2372       "WWAT (R[n], DSP_R (m) >> 16);",
2373     },
2374   },
2375   { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
2376     {
2377       "WWAT (R[n], DSP_R (m) >> 16);",
2378       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2379     },
2380   },
2381   { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
2382     {
2383       "WWAT (R[n], DSP_R (m) >> 16);",
2384       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2385     },
2386   },
2387   { "", "n", "movy.l @<REG_yx>,<DSP_YX>",   "111100yxYX100001",
2388     {
2389       "DSP_R (m) = RLAT (R[n]);",
2390     },
2391   },
2392   { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
2393     {
2394       "DSP_R (m) = RLAT (R[n]);",
2395       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2396     },
2397   },
2398   { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
2399     {
2400       "DSP_R (m) = RLAT (R[n]);",
2401       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2402     },
2403   },
2404   { "", "n", "movy.l <DSP_Ay>,@<REG_yx>",   "111100yxAY110001",
2405     {
2406       "WLAT (R[n], DSP_R (m));",
2407     },
2408   },
2409   { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
2410     {
2411       "WLAT (R[n], DSP_R (m));",
2412       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2413     },
2414   },
2415   { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
2416     {
2417       "WLAT (R[n], DSP_R (m));",
2418       "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2419     },
2420   },
2421   { "", "", "nopx nopy", "1111000000000000",
2422     {
2423       "/* nop */",
2424     },
2425   },
2426   { "", "", "ppi", "1111100000000000",
2427     {
2428       "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
2429       "ppi_insn (RIAT (nip));",
2430       "SET_NIP (nip + 2);",
2431       "iword &= 0xf7ff; goto top;",
2432     },
2433   },
2434 #endif
2435   {},
2436 };
2437 
2438 static op ppi_tab[] =
2439 {
2440   { "","", "pshl #<imm>,dz",	"00000iiim16.zzzz",
2441     {
2442       "int Sz = DSP_R (z) & 0xffff0000;",
2443       "",
2444       "if (i <= 16)",
2445       "  res = Sz << i;",
2446       "else if (i >= 128 - 16)",
2447       "  res = (unsigned) Sz >> (128 - i);	/* no sign extension */",
2448       "else",
2449       "  {",
2450       "    RAISE_EXCEPTION (SIGILL);",
2451       "    return;",
2452       "  }",
2453       "res &= 0xffff0000;",
2454       "res_grd = 0;",
2455       "goto logical;",
2456     },
2457   },
2458   { "","", "psha #<imm>,dz",	"00010iiim32.zzzz",
2459     {
2460       "int Sz = DSP_R (z);",
2461       "int Sz_grd = GET_DSP_GRD (z);",
2462       "",
2463       "if (i <= 32)",
2464       "  {",
2465       "    if (i == 32)",
2466       "      {",
2467       "        res = 0;",
2468       "        res_grd = Sz;",
2469       "      }",
2470       "    else",
2471       "      {",
2472       "        res = Sz << i;",
2473       "        res_grd = Sz_grd << i | (unsigned) Sz >> (32 - i);",
2474       "      }",
2475       "    res_grd = SEXT (res_grd);",
2476       "    carry = res_grd & 1;",
2477       "  }",
2478       "else if (i >= 96)",
2479       "  {",
2480       "    i = 128 - i;",
2481       "    if (i == 32)",
2482       "      {",
2483       "        res_grd = SIGN32 (Sz_grd);",
2484       "        res = Sz_grd;",
2485       "      }",
2486       "    else",
2487       "      {",
2488       "        res = Sz >> i | Sz_grd << (32 - i);",
2489       "        res_grd = Sz_grd >> i;",
2490       "      }",
2491       "    carry = Sz >> (i - 1) & 1;",
2492       "  }",
2493       "else",
2494       "  {",
2495       "    RAISE_EXCEPTION (SIGILL);",
2496       "    return;",
2497       "  }",
2498       "COMPUTE_OVERFLOW;",
2499       "greater_equal = 0;",
2500     },
2501   },
2502   { "","", "pmuls Se,Sf,Dg",	"0100eeff0000gg00",
2503     {
2504       "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2505       "if (res == 0x80000000)",
2506       "  res = 0x7fffffff;",
2507       "DSP_R (g) = res;",
2508       "DSP_GRD (g) = SIGN32 (res);",
2509       "return;",
2510     },
2511   },
2512   { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg",	"0110eeffxxyygguu",
2513     {
2514       "int Sx = DSP_R (x);",
2515       "int Sx_grd = GET_DSP_GRD (x);",
2516       "int Sy = DSP_R (y);",
2517       "int Sy_grd = SIGN32 (Sy);",
2518       "",
2519       "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2520       "if (res == 0x80000000)",
2521       "  res = 0x7fffffff;",
2522       "DSP_R (g) = res;",
2523       "DSP_GRD (g) = SIGN32 (res);",
2524       "",
2525       "z = u;",
2526       "res = Sx - Sy;",
2527       "carry = (unsigned) res > (unsigned) Sx;",
2528       "res_grd = Sx_grd - Sy_grd - carry;",
2529       "COMPUTE_OVERFLOW;",
2530       "ADD_SUB_GE;",
2531     },
2532   },
2533   { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg",	"0111eeffxxyygguu",
2534     {
2535       "int Sx = DSP_R (x);",
2536       "int Sx_grd = GET_DSP_GRD (x);",
2537       "int Sy = DSP_R (y);",
2538       "int Sy_grd = SIGN32 (Sy);",
2539       "",
2540       "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2541       "if (res == 0x80000000)",
2542       "  res = 0x7fffffff;",
2543       "DSP_R (g) = res;",
2544       "DSP_GRD (g) = SIGN32 (res);",
2545       "",
2546       "z = u;",
2547       "res = Sx + Sy;",
2548       "carry = (unsigned) res < (unsigned) Sx;",
2549       "res_grd = Sx_grd + Sy_grd + carry;",
2550       "COMPUTE_OVERFLOW;",
2551     },
2552   },
2553   { "","", "psubc Sx,Sy,Dz",		"10100000xxyyzzzz",
2554     {
2555       "int Sx = DSP_R (x);",
2556       "int Sx_grd = GET_DSP_GRD (x);",
2557       "int Sy = DSP_R (y);",
2558       "int Sy_grd = SIGN32 (Sy);",
2559       "",
2560       "res = Sx - Sy - (DSR & 1);",
2561       "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
2562       "res_grd = Sx_grd + Sy_grd + carry;",
2563       "COMPUTE_OVERFLOW;",
2564       "ADD_SUB_GE;",
2565       "DSR &= ~0xf1;\n",
2566       "if (res || res_grd)\n",
2567       "  DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n",
2568       "else\n",
2569       "  DSR |= DSR_MASK_Z | overflow;\n",
2570       "DSR |= carry;\n",
2571       "goto assign_z;\n",
2572     },
2573   },
2574   { "","", "paddc Sx,Sy,Dz",	"10110000xxyyzzzz",
2575     {
2576       "int Sx = DSP_R (x);",
2577       "int Sx_grd = GET_DSP_GRD (x);",
2578       "int Sy = DSP_R (y);",
2579       "int Sy_grd = SIGN32 (Sy);",
2580       "",
2581       "res = Sx + Sy + (DSR & 1);",
2582       "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
2583       "res_grd = Sx_grd + Sy_grd + carry;",
2584       "COMPUTE_OVERFLOW;",
2585       "ADD_SUB_GE;",
2586       "DSR &= ~0xf1;\n",
2587       "if (res || res_grd)\n",
2588       "  DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n",
2589       "else\n",
2590       "  DSR |= DSR_MASK_Z | overflow;\n",
2591       "DSR |= carry;\n",
2592       "goto assign_z;\n",
2593     },
2594   },
2595   { "","", "pcmp Sx,Sy",	"10000100xxyyzzzz",
2596     {
2597       "int Sx = DSP_R (x);",
2598       "int Sx_grd = GET_DSP_GRD (x);",
2599       "int Sy = DSP_R (y);",
2600       "int Sy_grd = SIGN32 (Sy);",
2601       "",
2602       "z = 17; /* Ignore result.  */",
2603       "res = Sx - Sy;",
2604       "carry = (unsigned) res > (unsigned) Sx;",
2605       "res_grd = Sx_grd - Sy_grd - carry;",
2606       "COMPUTE_OVERFLOW;",
2607       "ADD_SUB_GE;",
2608     },
2609   },
2610   { "","", "pwsb Sx,Sy,Dz",	"10100100....zzzz",
2611     {
2612       "return;",
2613     },
2614   },
2615   { "","", "pwad Sx,Sy,Dz",	"10110100....zzzz",
2616     {
2617       "return;",
2618     },
2619   },
2620   { "","", "(if cc) pabs Sx,Dz",	"100010ccxx01zzzz",
2621     {
2622       "/* FIXME: duplicate code pabs.  */",
2623       "res = DSP_R (x);",
2624       "res_grd = GET_DSP_GRD (x);",
2625       "if (res >= 0)",
2626       "  carry = 0;",
2627       "else",
2628       "  {",
2629       "    res = -res;",
2630       "    carry = (res != 0); /* The manual has a bug here.  */",
2631       "    res_grd = -res_grd - carry;",
2632       "  }",
2633       "COMPUTE_OVERFLOW;",
2634       "/* ??? The re-computing of overflow after",
2635       "   saturation processing is specific to pabs.  */",
2636       "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2637       "ADD_SUB_GE;",
2638     },
2639   },
2640   { "","", "pabs Sx,Dz",	"10001000xx..zzzz",
2641     {
2642       "res = DSP_R (x);",
2643       "res_grd = GET_DSP_GRD (x);",
2644       "if (res >= 0)",
2645       "  carry = 0;",
2646       "else",
2647       "  {",
2648       "    res = -res;",
2649       "    carry = (res != 0); /* The manual has a bug here.  */",
2650       "    res_grd = -res_grd - carry;",
2651       "  }",
2652       "COMPUTE_OVERFLOW;",
2653       "/* ??? The re-computing of overflow after",
2654       "   saturation processing is specific to pabs.  */",
2655       "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2656       "ADD_SUB_GE;",
2657     },
2658   },
2659 
2660   { "","", "(if cc) prnd Sx,Dz",	"100110ccxx01zzzz",
2661     {
2662       "/* FIXME: duplicate code prnd.  */",
2663       "int Sx = DSP_R (x);",
2664       "int Sx_grd = GET_DSP_GRD (x);",
2665       "",
2666       "res = (Sx + 0x8000) & 0xffff0000;",
2667       "carry = (unsigned) res < (unsigned) Sx;",
2668       "res_grd = Sx_grd + carry;",
2669       "COMPUTE_OVERFLOW;",
2670       "ADD_SUB_GE;",
2671     },
2672   },
2673   { "","", "prnd Sx,Dz",	"10011000xx..zzzz",
2674     {
2675       "int Sx = DSP_R (x);",
2676       "int Sx_grd = GET_DSP_GRD (x);",
2677       "",
2678       "res = (Sx + 0x8000) & 0xffff0000;",
2679       "carry = (unsigned) res < (unsigned) Sx;",
2680       "res_grd = Sx_grd + carry;",
2681       "COMPUTE_OVERFLOW;",
2682       "ADD_SUB_GE;",
2683     },
2684   },
2685 
2686   { "","", "(if cc) pabs Sy,Dz",	"101010cc01yyzzzz",
2687     {
2688       "/* FIXME: duplicate code pabs.  */",
2689       "res = DSP_R (y);",
2690       "res_grd = 0;",
2691       "overflow = 0;",
2692       "greater_equal = DSR_MASK_G;",
2693       "if (res >= 0)",
2694       "  carry = 0;",
2695       "else",
2696       "  {",
2697       "    res = -res;",
2698       "    carry = 1;",
2699       "    if (res < 0)",
2700       "      {",
2701       "        if (S)",
2702       "          res = 0x7fffffff;",
2703       "        else",
2704       "          {",
2705       "            overflow = DSR_MASK_V;",
2706       "            greater_equal = 0;",
2707       "          }",
2708       "      }",
2709       "  }",
2710     },
2711   },
2712   { "","", "pabs Sy,Dz",	"10101000..yyzzzz",
2713     {
2714       "res = DSP_R (y);",
2715       "res_grd = 0;",
2716       "overflow = 0;",
2717       "greater_equal = DSR_MASK_G;",
2718       "if (res >= 0)",
2719       "  carry = 0;",
2720       "else",
2721       "  {",
2722       "    res = -res;",
2723       "    carry = 1;",
2724       "    if (res < 0)",
2725       "      {",
2726       "        if (S)",
2727       "          res = 0x7fffffff;",
2728       "        else",
2729       "          {",
2730       "            overflow = DSR_MASK_V;",
2731       "            greater_equal = 0;",
2732       "          }",
2733       "      }",
2734       "  }",
2735     },
2736   },
2737   { "","", "(if cc) prnd Sy,Dz",	"101110cc01yyzzzz",
2738     {
2739       "/* FIXME: duplicate code prnd.  */",
2740       "int Sy = DSP_R (y);",
2741       "int Sy_grd = SIGN32 (Sy);",
2742       "",
2743       "res = (Sy + 0x8000) & 0xffff0000;",
2744       "carry = (unsigned) res < (unsigned) Sy;",
2745       "res_grd = Sy_grd + carry;",
2746       "COMPUTE_OVERFLOW;",
2747       "ADD_SUB_GE;",
2748     },
2749   },
2750   { "","", "prnd Sy,Dz",	"10111000..yyzzzz",
2751     {
2752       "int Sy = DSP_R (y);",
2753       "int Sy_grd = SIGN32 (Sy);",
2754       "",
2755       "res = (Sy + 0x8000) & 0xffff0000;",
2756       "carry = (unsigned) res < (unsigned) Sy;",
2757       "res_grd = Sy_grd + carry;",
2758       "COMPUTE_OVERFLOW;",
2759       "ADD_SUB_GE;",
2760     },
2761   },
2762   { "","", "(if cc) pshl Sx,Sy,Dz",	"100000ccxxyyzzzz",
2763     {
2764       "int Sx = DSP_R (x) & 0xffff0000;",
2765       "int Sy = DSP_R (y) >> 16 & 0x7f;",
2766       "",
2767       "if (Sy <= 16)",
2768       "  res = Sx << Sy;",
2769       "else if (Sy >= 128 - 16)",
2770       "  res = (unsigned) Sx >> (128 - Sy);	/* no sign extension */",
2771       "else",
2772       "  {",
2773       "    RAISE_EXCEPTION (SIGILL);",
2774       "    return;",
2775       "  }",
2776       "goto cond_logical;",
2777     },
2778   },
2779   { "","", "(if cc) psha Sx,Sy,Dz",	"100100ccxxyyzzzz",
2780     {
2781       "int Sx = DSP_R (x);",
2782       "int Sx_grd = GET_DSP_GRD (x);",
2783       "int Sy = DSP_R (y) >> 16 & 0x7f;",
2784       "",
2785       "if (Sy <= 32)",
2786       "  {",
2787       "    if (Sy == 32)",
2788       "      {",
2789       "        res = 0;",
2790       "        res_grd = Sx;",
2791       "      }",
2792       "    else",
2793       "      {",
2794       "        res = Sx << Sy;",
2795       "        res_grd = Sx_grd << Sy | (unsigned) Sx >> (32 - Sy);",
2796       "      }",
2797       "    res_grd = SEXT (res_grd);",
2798       "    carry = res_grd & 1;",
2799       "  }",
2800       "else if (Sy >= 96)",
2801       "  {",
2802       "    Sy = 128 - Sy;",
2803       "    if (Sy == 32)",
2804       "      {",
2805       "        res_grd = SIGN32 (Sx_grd);",
2806       "        res = Sx_grd;",
2807       "      }",
2808       "    else",
2809       "      {",
2810       "        res = Sx >> Sy | Sx_grd << (32 - Sy);",
2811       "        res_grd = Sx_grd >> Sy;",
2812       "      }",
2813       "    carry = Sx >> (Sy - 1) & 1;",
2814       "  }",
2815       "else",
2816       "  {",
2817       "    RAISE_EXCEPTION (SIGILL);",
2818       "    return;",
2819       "  }",
2820       "COMPUTE_OVERFLOW;",
2821       "greater_equal = 0;",
2822     },
2823   },
2824   { "","", "(if cc) psub Sx,Sy,Dz",	"101000ccxxyyzzzz",
2825     {
2826       "int Sx = DSP_R (x);",
2827       "int Sx_grd = GET_DSP_GRD (x);",
2828       "int Sy = DSP_R (y);",
2829       "int Sy_grd = SIGN32 (Sy);",
2830       "",
2831       "res = Sx - Sy;",
2832       "carry = (unsigned) res > (unsigned) Sx;",
2833       "res_grd = Sx_grd - Sy_grd - carry;",
2834       "COMPUTE_OVERFLOW;",
2835       "ADD_SUB_GE;",
2836     },
2837   },
2838   { "","", "(if cc) psub Sy,Sx,Dz",	"100001ccxxyyzzzz",
2839     {
2840       "int Sx = DSP_R (x);",
2841       "int Sx_grd = GET_DSP_GRD (x);",
2842       "int Sy = DSP_R (y);",
2843       "int Sy_grd = SIGN32 (Sy);",
2844       "",
2845       "res = Sy - Sx;",
2846       "carry = (unsigned) res > (unsigned) Sy;",
2847       "res_grd = Sy_grd - Sx_grd - carry;",
2848       "COMPUTE_OVERFLOW;",
2849       "ADD_SUB_GE;",
2850     },
2851   },
2852   { "","", "(if cc) padd Sx,Sy,Dz",	"101100ccxxyyzzzz",
2853     {
2854       "int Sx = DSP_R (x);",
2855       "int Sx_grd = GET_DSP_GRD (x);",
2856       "int Sy = DSP_R (y);",
2857       "int Sy_grd = SIGN32 (Sy);",
2858       "",
2859       "res = Sx + Sy;",
2860       "carry = (unsigned) res < (unsigned) Sx;",
2861       "res_grd = Sx_grd + Sy_grd + carry;",
2862       "COMPUTE_OVERFLOW;",
2863       "ADD_SUB_GE;",
2864     },
2865   },
2866   { "","", "(if cc) pand Sx,Sy,Dz",	"100101ccxxyyzzzz",
2867     {
2868       "res = DSP_R (x) & DSP_R (y);",
2869     "cond_logical:",
2870       "res &= 0xffff0000;",
2871       "res_grd = 0;",
2872       "if (iword & 0x200)\n",
2873       "  goto assign_z;\n",
2874     "logical:",
2875       "carry = 0;",
2876       "overflow = 0;",
2877       "greater_equal = 0;",
2878       "DSR &= ~0xf1;\n",
2879       "if (res)\n",
2880       "  DSR |= res >> 26 & DSR_MASK_N;\n",
2881       "else\n",
2882       "  DSR |= DSR_MASK_Z;\n",
2883       "goto assign_dc;\n",
2884     },
2885   },
2886   { "","", "(if cc) pxor Sx,Sy,Dz",	"101001ccxxyyzzzz",
2887     {
2888       "res = DSP_R (x) ^ DSP_R (y);",
2889       "goto cond_logical;",
2890     },
2891   },
2892   { "","", "(if cc) por Sx,Sy,Dz",	"101101ccxxyyzzzz",
2893     {
2894       "res = DSP_R (x) | DSP_R (y);",
2895       "goto cond_logical;",
2896     },
2897   },
2898   { "","", "(if cc) pdec Sx,Dz",	"100010ccxx..zzzz",
2899     {
2900       "int Sx = DSP_R (x);",
2901       "int Sx_grd = GET_DSP_GRD (x);",
2902       "",
2903       "res = Sx - 0x10000;",
2904       "carry = Sx < (INT_MIN + 0x10000);",
2905       "res_grd = Sx_grd - carry;",
2906       "COMPUTE_OVERFLOW;",
2907       "ADD_SUB_GE;",
2908       "res &= 0xffff0000;",
2909     },
2910   },
2911   { "","", "(if cc) pinc Sx,Dz",	"100110ccxx..zzzz",
2912     {
2913       "int Sx = DSP_R (x);",
2914       "int Sx_grd = GET_DSP_GRD (x);",
2915       "",
2916       "res = Sx + 0x10000;",
2917       "carry = Sx > (INT_MAX - 0x10000);",
2918       "res_grd = Sx_grd + carry;",
2919       "COMPUTE_OVERFLOW;",
2920       "ADD_SUB_GE;",
2921       "res &= 0xffff0000;",
2922     },
2923   },
2924   { "","", "(if cc) pdec Sy,Dz",	"101010cc..yyzzzz",
2925     {
2926       "int Sy = DSP_R (y);",
2927       "int Sy_grd = SIGN32 (Sy);",
2928       "",
2929       "res = Sy - 0x10000;",
2930       "carry = Sy < (INT_MIN + 0x10000);",
2931       "res_grd = Sy_grd - carry;",
2932       "COMPUTE_OVERFLOW;",
2933       "ADD_SUB_GE;",
2934       "res &= 0xffff0000;",
2935     },
2936   },
2937   { "","", "(if cc) pinc Sy,Dz",	"101110cc..yyzzzz",
2938     {
2939       "int Sy = DSP_R (y);",
2940       "int Sy_grd = SIGN32 (Sy);",
2941       "",
2942       "res = Sy + 0x10000;",
2943       "carry = Sy > (INT_MAX - 0x10000);",
2944       "res_grd = Sy_grd + carry;",
2945       "COMPUTE_OVERFLOW;",
2946       "ADD_SUB_GE;",
2947       "res &= 0xffff0000;",
2948     },
2949   },
2950   { "","", "(if cc) pclr Dz",		"100011cc....zzzz",
2951     {
2952       "res = 0;",
2953       "res_grd = 0;",
2954       "carry = 0;",
2955       "overflow = 0;",
2956       "greater_equal = 1;",
2957     },
2958   },
2959   { "","", "pclr Du pmuls Se,Sf,Dg",	"0100eeff0001gguu",
2960     {
2961       "/* Do multiply.  */",
2962       "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2963       "if (res == 0x80000000)",
2964       "  res = 0x7fffffff;",
2965       "DSP_R (g) = res;",
2966       "DSP_GRD (g) = SIGN32 (res);",
2967       "/* FIXME: update DSR based on results of multiply!  */",
2968       "",
2969       "/* Do clr.  */",
2970       "z = u;",
2971       "res = 0;",
2972       "res_grd = 0;",
2973       "goto assign_z;",
2974     },
2975   },
2976   { "","", "(if cc) pdmsb Sx,Dz",	"100111ccxx..zzzz",
2977     {
2978       "unsigned Sx = DSP_R (x);",
2979       "int Sx_grd = GET_DSP_GRD (x);",
2980       "int i = 16;",
2981       "",
2982       "if (Sx_grd < 0)",
2983       "  {",
2984       "    Sx_grd = ~Sx_grd;",
2985       "    Sx = ~Sx;",
2986       "  }",
2987       "if (Sx_grd)",
2988       "  {",
2989       "    Sx = Sx_grd;",
2990       "    res = -2;",
2991       "  }",
2992       "else if (Sx)",
2993       "  res = 30;",
2994       "else",
2995       "  res = 31;",
2996       "do",
2997       "  {",
2998       "    if (Sx & ((unsigned)~0 << i))",
2999       "      {",
3000       "        res -= i;",
3001       "        Sx >>= i;",
3002       "      }",
3003       "  }",
3004       "while (i >>= 1);",
3005       "res <<= 16;",
3006       "res_grd = SIGN32 (res);",
3007       "carry = 0;",
3008       "overflow = 0;",
3009       "ADD_SUB_GE;",
3010     },
3011   },
3012   { "","", "(if cc) pdmsb Sy,Dz",	"101111cc..yyzzzz",
3013     {
3014       "unsigned Sy = DSP_R (y);",
3015       "int i = 16;",
3016       "",
3017       "if (Sy < 0)",
3018       "  Sy = ~Sy;",
3019       "Sy <<= 1;",
3020       "res = 31;",
3021       "do",
3022       "  {",
3023       "    if (Sy & ((unsigned)~0 << i))",
3024       "      {",
3025       "        res -= i;",
3026       "        Sy >>= i;",
3027       "      }",
3028       "  }",
3029       "while (i >>= 1);",
3030       "res <<= 16;",
3031       "res_grd = SIGN32 (res);",
3032       "carry = 0;",
3033       "overflow = 0;",
3034       "ADD_SUB_GE;",
3035     },
3036   },
3037   { "","", "(if cc) pneg Sx,Dz",	"110010ccxx..zzzz",
3038     {
3039       "int Sx = DSP_R (x);",
3040       "int Sx_grd = GET_DSP_GRD (x);",
3041       "",
3042       "res = 0 - Sx;",
3043       "carry = res != 0;",
3044       "res_grd = 0 - Sx_grd - carry;",
3045       "COMPUTE_OVERFLOW;",
3046       "ADD_SUB_GE;",
3047     },
3048   },
3049   { "","", "(if cc) pcopy Sx,Dz",	"110110ccxx..zzzz",
3050     {
3051       "res = DSP_R (x);",
3052       "res_grd = GET_DSP_GRD (x);",
3053       "carry = 0;",
3054       "COMPUTE_OVERFLOW;",
3055       "ADD_SUB_GE;",
3056     },
3057   },
3058   { "","", "(if cc) pneg Sy,Dz",	"111010cc..yyzzzz",
3059     {
3060       "int Sy = DSP_R (y);",
3061       "int Sy_grd = SIGN32 (Sy);",
3062       "",
3063       "res = 0 - Sy;",
3064       "carry = res != 0;",
3065       "res_grd = 0 - Sy_grd - carry;",
3066       "COMPUTE_OVERFLOW;",
3067       "ADD_SUB_GE;",
3068     },
3069   },
3070   { "","", "(if cc) pcopy Sy,Dz",	"111110cc..yyzzzz",
3071     {
3072       "res = DSP_R (y);",
3073       "res_grd = SIGN32 (res);",
3074       "carry = 0;",
3075       "COMPUTE_OVERFLOW;",
3076       "ADD_SUB_GE;",
3077     },
3078   },
3079   { "","", "(if cc) psts MACH,Dz",	"110011cc....zzzz",
3080     {
3081       "res = MACH;",
3082       "res_grd = SIGN32 (res);",
3083       "goto assign_z;",
3084     },
3085   },
3086   { "","", "(if cc) psts MACL,Dz",	"110111cc....zzzz",
3087     {
3088       "res = MACL;",
3089       "res_grd = SIGN32 (res);",
3090       "goto assign_z;",
3091     },
3092   },
3093   { "","", "(if cc) plds Dz,MACH",	"111011cc....zzzz",
3094     {
3095       "if (0xa05f >> z & 1)",
3096       "  RAISE_EXCEPTION (SIGILL);",
3097       "else",
3098       "  MACH = DSP_R (z);",
3099       "return;",
3100     },
3101   },
3102   { "","", "(if cc) plds Dz,MACL",	"111111cc....zzzz",
3103     {
3104       "if (0xa05f >> z & 1)",
3105       "  RAISE_EXCEPTION (SIGILL);",
3106       "else",
3107       "  MACL = DSP_R (z);",
3108       "return;",
3109     },
3110   },
3111   /* sh4a */
3112   { "","", "(if cc) pswap Sx,Dz",	"100111ccxx01zzzz",
3113     {
3114       "int Sx = DSP_R (x);",
3115       "",
3116       "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
3117       "res_grd = GET_DSP_GRD (x);",
3118       "carry = 0;",
3119       "overflow = 0;",
3120       "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
3121     },
3122   },
3123   /* sh4a */
3124   { "","", "(if cc) pswap Sy,Dz",	"101111cc01yyzzzz",
3125     {
3126       "int Sy = DSP_R (y);",
3127       "",
3128       "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
3129       "res_grd = SIGN32 (Sy);",
3130       "carry = 0;",
3131       "overflow = 0;",
3132       "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
3133     },
3134   },
3135 
3136   {},
3137 };
3138 
3139 static int
3140 qfunc (const void *va, const void *vb)
3141 {
3142   const op *a = va;
3143   const op *b = vb;
3144   char bufa[9];
3145   char bufb[9];
3146   int diff;
3147 
3148   memcpy (bufa, a->code, 4);
3149   memcpy (bufa + 4, a->code + 12, 4);
3150   bufa[8] = 0;
3151 
3152   memcpy (bufb, b->code, 4);
3153   memcpy (bufb + 4, b->code + 12, 4);
3154   bufb[8] = 0;
3155   diff = strcmp (bufa, bufb);
3156   /* Stabilize the sort, so that later entries can override more general
3157      preceding entries.  */
3158   return diff ? diff : a - b;
3159 }
3160 
3161 static void
3162 sorttab (void)
3163 {
3164   op *p = tab;
3165   int len = 0;
3166 
3167   while (p->name)
3168     {
3169       p++;
3170       len++;
3171     }
3172   qsort (tab, len, sizeof (*p), qfunc);
3173 }
3174 
3175 static void
3176 gengastab (void)
3177 {
3178   op *p;
3179   sorttab ();
3180   for (p = tab; p->name; p++)
3181     {
3182       printf ("%s %-30s\n", p->code, p->name);
3183     }
3184 }
3185 
3186 static unsigned short table[1 << 16];
3187 
3188 static int warn_conflicts = 0;
3189 
3190 static void
3191 conflict_warn (int val, int i)
3192 {
3193   int ix, key;
3194   int j = table[val];
3195 
3196   fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
3197 	   val, i, table[val]);
3198 
3199   for (ix = ARRAY_SIZE (tab); ix >= 0; ix--)
3200     if (tab[ix].index == i || tab[ix].index == j)
3201       {
3202 	key = ((tab[ix].code[0] - '0') << 3) +
3203 	  ((tab[ix].code[1] - '0') << 2) +
3204 	  ((tab[ix].code[2] - '0') << 1) +
3205 	  ((tab[ix].code[3] - '0'));
3206 
3207 	if (val >> 12 == key)
3208 	  fprintf (stderr, "  %s -- %s\n", tab[ix].code, tab[ix].name);
3209       }
3210 
3211   for (ix = ARRAY_SIZE (movsxy_tab); ix >= 0; ix--)
3212     if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
3213       {
3214 	key = ((movsxy_tab[ix].code[0] - '0') << 3) +
3215 	  ((movsxy_tab[ix].code[1] - '0') << 2) +
3216 	  ((movsxy_tab[ix].code[2] - '0') << 1) +
3217 	  ((movsxy_tab[ix].code[3] - '0'));
3218 
3219 	if (val >> 12 == key)
3220 	  fprintf (stderr, "  %s -- %s\n",
3221 		   movsxy_tab[ix].code, movsxy_tab[ix].name);
3222       }
3223 
3224   for (ix = ARRAY_SIZE (ppi_tab); ix >= 0; ix--)
3225     if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
3226       {
3227 	key = ((ppi_tab[ix].code[0] - '0') << 3) +
3228 	  ((ppi_tab[ix].code[1] - '0') << 2) +
3229 	  ((ppi_tab[ix].code[2] - '0') << 1) +
3230 	  ((ppi_tab[ix].code[3] - '0'));
3231 
3232 	if (val >> 12 == key)
3233 	  fprintf (stderr, "  %s -- %s\n",
3234 		   ppi_tab[ix].code, ppi_tab[ix].name);
3235       }
3236 }
3237 
3238 /* Take an opcode, expand all varying fields in it out and fill all the
3239    right entries in 'table' with the opcode index.  */
3240 
3241 static void
3242 expand_opcode (int val, int i, const char *s)
3243 {
3244   if (*s == 0)
3245     {
3246       if (warn_conflicts && table[val] != 0)
3247 	conflict_warn (val, i);
3248       table[val] = i;
3249     }
3250   else
3251     {
3252       int j = 0, m = 0;
3253 
3254       switch (s[0])
3255 	{
3256 	default:
3257 	  fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
3258 	  exit (1);
3259 	case '0':
3260 	case '1':
3261 	  /* Consume an arbitrary number of ones and zeros.  */
3262 	  do {
3263 	    j = (j << 1) + (s[m++] - '0');
3264 	  } while (s[m] == '0' || s[m] == '1');
3265 	  expand_opcode ((val << m) | j, i, s + m);
3266 	  break;
3267 	case 'N':	/* NN -- four-way fork */
3268 	  for (j = 0; j < 4; j++)
3269 	    expand_opcode ((val << 2) | j, i, s + 2);
3270 	  break;
3271 	case 'x':	/* xx or xy -- two-way or four-way fork */
3272 	  for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1))
3273 	    expand_opcode ((val << 2) | j, i, s + 2);
3274 	  break;
3275 	case 'y':	/* yy or yx -- two-way or four-way fork */
3276 	  for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++)
3277 	    expand_opcode ((val << 2) | j, i, s + 2);
3278 	  break;
3279 	case '?':	/* Seven-way "wildcard" fork for movxy */
3280 	  expand_opcode ((val << 2), i, s + 2);
3281 	  for (j = 1; j < 4; j++)
3282 	    {
3283 	      expand_opcode ((val << 2) | j, i, s + 2);
3284 	      expand_opcode ((val << 2) | (j + 16), i, s + 2);
3285 	    }
3286 	  break;
3287 	case 'i':	/* eg. "i8*1" */
3288 	case '.':	/* "...." is a wildcard */
3289 	case 'n':
3290 	case 'm':
3291 	  /* nnnn, mmmm, i#*#, .... -- 16-way fork.  */
3292 	  for (j = 0; j < 16; j++)
3293 	    expand_opcode ((val << 4) | j, i, s + 4);
3294 	  break;
3295 	case 'e':
3296 	  /* eeee -- even numbered register:
3297 	     8 way fork.  */
3298 	  for (j = 0; j < 15; j += 2)
3299 	    expand_opcode ((val << 4) | j, i, s + 4);
3300 	  break;
3301 	case 'M':
3302 	  /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
3303 	     MMMM -- 10-way fork */
3304 	  expand_opcode ((val << 4) | 5, i, s + 4);
3305 	  for (j = 7; j < 16; j++)
3306 	    expand_opcode ((val << 4) | j, i, s + 4);
3307 	  break;
3308 	case 'G':
3309 	  /* A1G, A0G:
3310 	     GGGG -- two-way fork */
3311 	  for (j = 13; j <= 15; j +=2)
3312 	    expand_opcode ((val << 4) | j, i, s + 4);
3313 	  break;
3314 	case 's':
3315 	  /* ssss -- 10-way fork */
3316 	  /* System registers mach, macl, pr: */
3317 	  for (j = 0; j < 3; j++)
3318 	    expand_opcode ((val << 4) | j, i, s + 4);
3319 	  /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
3320 	  for (j = 5; j < 12; j++)
3321 	    expand_opcode ((val << 4) | j, i, s + 4);
3322 	  break;
3323 	case 'X':
3324 	  /* XX/XY -- 2/4 way fork.  */
3325 	  for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1))
3326 	    expand_opcode ((val << 2) | j, i, s + 2);
3327 	  break;
3328 	case 'a':
3329 	  /* aa/ax -- 2/4 way fork.  */
3330 	  for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1))
3331 	    expand_opcode ((val << 2) | j, i, s + 2);
3332 	  break;
3333 	case 'Y':
3334 	  /* YY/YX -- 2/4 way fork.  */
3335 	  for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1)
3336 	    expand_opcode ((val << 2) | j, i, s + 2);
3337 	  break;
3338 	case 'A':
3339 	  /* AA/AY: 2/4 way fork.  */
3340 	  for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1)
3341 	    expand_opcode ((val << 2) | j, i, s + 2);
3342 	  break;
3343 	case 'v':
3344 	  /* vv(VV) -- 4(16) way fork.  */
3345 	  /* Vector register fv0/4/8/12.  */
3346 	  if (s[2] == 'V')
3347 	    {
3348 	      /* 2 vector registers.  */
3349 	      for (j = 0; j < 15; j++)
3350 		expand_opcode ((val << 4) | j, i, s + 4);
3351 	    }
3352 	  else
3353 	    {
3354 	      /* 1 vector register.  */
3355 	      for (j = 0; j < 4; j += 1)
3356 		expand_opcode ((val << 2) | j, i, s + 2);
3357 	    }
3358 	  break;
3359 	}
3360     }
3361 }
3362 
3363 /* Print the jump table used to index an opcode into a switch
3364    statement entry.  */
3365 
3366 static void
3367 dumptable (const char *name, int size, int start)
3368 {
3369   int lump = 256;
3370   int online = 16;
3371 
3372   int i = start;
3373 
3374   printf ("unsigned short %s[%d] = {\n", name, size);
3375   while (i < start + size)
3376     {
3377       int j = 0;
3378 
3379       printf ("/* 0x%x */\n", i);
3380 
3381       while (j < lump)
3382 	{
3383 	  int k = 0;
3384 	  while (k < online)
3385 	    {
3386 	      printf ("%2d", table[i + j + k]);
3387 	      if (j + k < lump)
3388 		printf (",");
3389 
3390 	      k++;
3391 	    }
3392 	  j += k;
3393 	  printf ("\n");
3394 	}
3395       i += j;
3396     }
3397   printf ("};\n");
3398 }
3399 
3400 
3401 static void
3402 filltable (op *p)
3403 {
3404   static int index = 1;
3405 
3406   sorttab ();
3407   for (; p->name; p++)
3408     {
3409       p->index = index++;
3410       expand_opcode (0, p->index, p->code);
3411     }
3412 }
3413 
3414 /* Table already contains all the switch case tags for 16-bit opcode double
3415    data transfer (ddt) insns, and the switch case tag for processing parallel
3416    processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
3417    latter tag to represent all combinations of ppi with ddt.  */
3418 static void
3419 expand_ppi_movxy (void)
3420 {
3421   int i;
3422 
3423   for (i = 0xf000; i < 0xf400; i++)
3424     if (table[i])
3425       table[i + 0x800] = table[0xf800];
3426 }
3427 
3428 static void
3429 gensim_caselist (op *p)
3430 {
3431   for (; p->name; p++)
3432     {
3433       int j;
3434       int sextbit = -1;
3435       int needm = 0;
3436       int needn = 0;
3437       const char *s = p->code;
3438 
3439       printf ("  /* %s %s */\n", p->name, p->code);
3440       printf ("  case %d:\n", p->index);
3441 
3442       printf ("    {\n");
3443       while (*s)
3444 	{
3445 	  switch (*s)
3446 	    {
3447 	    default:
3448 	      fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
3449 		       *s);
3450 	      exit (1);
3451 	      break;
3452 	    case '?':
3453 	      /* Wildcard expansion, nothing to do here.  */
3454 	      s += 2;
3455 	      break;
3456 	    case 'v':
3457 	      printf ("      int v1 = ((iword >> 10) & 3) * 4;\n");
3458 	      s += 2;
3459 	      break;
3460 	    case 'V':
3461 	      printf ("      int v2 = ((iword >> 8)  & 3) * 4;\n");
3462 	      s += 2;
3463 	      break;
3464 	    case '0':
3465 	    case '1':
3466 	      s += 2;
3467 	      break;
3468 	    case '.':
3469 	      s += 4;
3470 	      break;
3471 	    case 'n':
3472 	    case 'e':
3473 	      printf ("      int n = (iword >> 8) & 0xf;\n");
3474 	      needn = 1;
3475 	      s += 4;
3476 	      break;
3477 	    case 'N':
3478 	      printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
3479 	      s += 2;
3480 	      break;
3481 	    case 'x':
3482 	      if (s[1] == 'y')	/* xy */
3483 		{
3484 		  printf ("      int n = (iword & 3) ?\n");
3485 		  printf ("              ((iword >> 9) & 1) + 4 :\n");
3486 		  printf ("              REG_xy ((iword >> 8) & 3);\n");
3487 		}
3488 	      else
3489 		printf ("      int n = ((iword >> 9) & 1) + 4;\n");
3490 	      needn = 1;
3491 	      s += 2;
3492 	      break;
3493 	    case 'y':
3494 	      if (s[1] == 'x')	/* yx */
3495 		{
3496 		  printf ("      int n = (iword & 0xc) ?\n");
3497 		  printf ("              ((iword >> 8) & 1) + 6 :\n");
3498 		  printf ("              REG_yx ((iword >> 8) & 3);\n");
3499 		}
3500 	      else
3501 		printf ("      int n = ((iword >> 8) & 1) + 6;\n");
3502 	      needn = 1;
3503 	      s += 2;
3504 	      break;
3505 	    case 'm':
3506 	      needm = 1;
3507 	    case 's':
3508 	    case 'M':
3509 	    case 'G':
3510 	      printf ("      int m = (iword >> 4) & 0xf;\n");
3511 	      s += 4;
3512 	      break;
3513 	    case 'X':
3514 	      if (s[1] == 'Y')	/* XY */
3515 		{
3516 		  printf ("      int m = (iword & 3) ?\n");
3517 		  printf ("              ((iword >> 7) & 1) + 8 :\n");
3518 		  printf ("              DSP_xy ((iword >> 6) & 3);\n");
3519 		}
3520 	      else
3521 		printf ("      int m = ((iword >> 7) & 1) + 8;\n");
3522 	      s += 2;
3523 	      break;
3524 	    case 'a':
3525 	      if (s[1] == 'x')	/* ax */
3526 		{
3527 		  printf ("      int m = (iword & 3) ?\n");
3528 		  printf ("              7 - ((iword >> 6) & 2) :\n");
3529 		  printf ("              DSP_ax ((iword >> 6) & 3);\n");
3530 		}
3531 	      else
3532 		printf ("      int m = 7 - ((iword >> 6) & 2);\n");
3533 	      s += 2;
3534 	      break;
3535 	    case 'Y':
3536 	      if (s[1] == 'X')	/* YX */
3537 		{
3538 		  printf ("      int m = (iword & 0xc) ?\n");
3539 		  printf ("              ((iword >> 6) & 1) + 10 :\n");
3540 		  printf ("              DSP_yx ((iword >> 6) & 3);\n");
3541 		}
3542 	      else
3543 		printf ("      int m = ((iword >> 6) & 1) + 10;\n");
3544 	      s += 2;
3545 	      break;
3546 	    case 'A':
3547 	      if (s[1] == 'Y')	/* AY */
3548 		{
3549 		  printf ("      int m = (iword & 0xc) ?\n");
3550 		  printf ("              7 - ((iword >> 5) & 2) :\n");
3551 		  printf ("              DSP_ay ((iword >> 6) & 3);\n");
3552 		}
3553 	      else
3554 		printf ("      int m = 7 - ((iword >> 5) & 2);\n");
3555 	      s += 2;
3556 	      break;
3557 
3558 	    case 'i':
3559 	      printf ("      int i = (iword & 0x");
3560 
3561 	      switch (s[1])
3562 		{
3563 		default:
3564 		  fprintf (stderr,
3565 			   "gensim_caselist: Unknown char '%c' in %s\n",
3566 			   s[1], s);
3567 		  exit (1);
3568 		  break;
3569 		case '4':
3570 		  printf ("f");
3571 		  break;
3572 		case '8':
3573 		  printf ("ff");
3574 		  break;
3575 		case '1':
3576 		  sextbit = 12;
3577 		  printf ("fff");
3578 		  break;
3579 		}
3580 	      printf (")");
3581 
3582 	      switch (s[3])
3583 		{
3584 		default:
3585 		  fprintf (stderr,
3586 			   "gensim_caselist: Unknown char '%c' in %s\n",
3587 			   s[3], s);
3588 		  exit (1);
3589 		  break;
3590 		case '.':	/* eg. "i12." */
3591 		  break;
3592 		case '1':
3593 		  break;
3594 		case '2':
3595 		  printf (" << 1");
3596 		  break;
3597 		case '4':
3598 		  printf (" << 2");
3599 		  break;
3600 		}
3601 	      printf (";\n");
3602 	      s += 4;
3603 	    }
3604 	}
3605       if (sextbit > 0)
3606 	{
3607 	  printf ("      i = (i ^ (1 << %d)) - (1 << %d);\n",
3608 		  sextbit - 1, sextbit - 1);
3609 	}
3610 
3611       if (needm && needn)
3612 	printf ("      TB (m,n);\n");
3613       else if (needm)
3614 	printf ("      TL (m);\n");
3615       else if (needn)
3616 	printf ("      TL (n);\n");
3617 
3618       {
3619 	/* Do the refs.  */
3620 	const char *r;
3621 	for (r = p->refs; *r; r++)
3622 	  {
3623 	    if (*r == 'f') printf ("      CREF (15);\n");
3624 	    if (*r == '-')
3625 	      {
3626 		printf ("      {\n");
3627 		printf ("        int i = n;\n");
3628 		printf ("        do {\n");
3629 		printf ("          CREF (i);\n");
3630 		printf ("        } while (i-- > 0);\n");
3631 		printf ("      }\n");
3632 	      }
3633 	    if (*r == '+')
3634 	      {
3635 		printf ("      {\n");
3636 		printf ("        int i = n;\n");
3637 		printf ("        do {\n");
3638 		printf ("          CREF (i);\n");
3639 		printf ("        } while (i++ < 14);\n");
3640 		printf ("      }\n");
3641 	      }
3642 	    if (*r == '0') printf ("      CREF (0);\n");
3643 	    if (*r == '8') printf ("      CREF (8);\n");
3644 	    if (*r == '9') printf ("      CREF (9);\n");
3645 	    if (*r == 'n') printf ("      CREF (n);\n");
3646 	    if (*r == 'm') printf ("      CREF (m);\n");
3647 	  }
3648       }
3649 
3650       printf ("      {\n");
3651       for (j = 0; j < MAX_NR_STUFF; j++)
3652 	{
3653 	  if (p->stuff[j])
3654 	    {
3655 	      printf ("        %s\n", p->stuff[j]);
3656 	    }
3657 	}
3658       printf ("      }\n");
3659 
3660       {
3661 	/* Do the defs.  */
3662 	const char *r;
3663 	for (r = p->defs; *r; r++)
3664 	  {
3665 	    if (*r == 'f') printf ("      CDEF (15);\n");
3666 	    if (*r == '-')
3667 	      {
3668 		printf ("      {\n");
3669 		printf ("        int i = n;\n");
3670 		printf ("        do {\n");
3671 		printf ("          CDEF (i);\n");
3672 		printf ("        } while (i-- > 0);\n");
3673 		printf ("      }\n");
3674 	      }
3675 	    if (*r == '+')
3676 	      {
3677 		printf ("      {\n");
3678 		printf ("        int i = n;\n");
3679 		printf ("        do {\n");
3680 		printf ("          CDEF (i);\n");
3681 		printf ("        } while (i++ < 14);\n");
3682 		printf ("      }\n");
3683 	      }
3684 	    if (*r == '0') printf ("      CDEF (0);\n");
3685 	    if (*r == 'n') printf ("      CDEF (n);\n");
3686 	    if (*r == 'm') printf ("      CDEF (m);\n");
3687 	  }
3688       }
3689 
3690       printf ("      break;\n");
3691       printf ("    }\n");
3692     }
3693 }
3694 
3695 static void
3696 gensim (void)
3697 {
3698   printf ("{\n");
3699   printf ("/* REG_xy = [r4, r5, r0, r1].  */\n");
3700   printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ?  0 :  1)\n");
3701   printf ("/* REG_yx = [r6, r7, r2, r3].  */\n");
3702   printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ?  2 :  3)\n");
3703   printf ("/* DSP_ax = [a0, a1, x0, x1].  */\n");
3704   printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ?  8 :  9)\n");
3705   printf ("/* DSP_ay = [a0, a1, y0, y1].  */\n");
3706   printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3707   printf ("/* DSP_xy = [x0, x1, y0, y1].  */\n");
3708   printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3709   printf ("/* DSP_yx = [y0, y1, x0, x1].  */\n");
3710   printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3711   printf ("  switch (jump_table[iword]) {\n");
3712 
3713   gensim_caselist (tab);
3714   gensim_caselist (movsxy_tab);
3715 
3716   printf ("  default:\n");
3717   printf ("    {\n");
3718   printf ("      RAISE_EXCEPTION (SIGILL);\n");
3719   printf ("    }\n");
3720   printf ("  }\n");
3721   printf ("}\n");
3722 }
3723 
3724 static void
3725 gendefines (void)
3726 {
3727   op *p;
3728   filltable (tab);
3729   for (p = tab; p->name; p++)
3730     {
3731       const char *s = p->name;
3732       printf ("#define OPC_");
3733       while (*s) {
3734 	if (isalpha (*s))
3735 	  printf ("%c", tolower (*s));
3736 	if (*s == ' ')
3737 	  printf ("_");
3738 	if (*s == '@')
3739 	  printf ("ind_");
3740 	if (*s == ',')
3741 	  printf ("_");
3742 	s++;
3743       }
3744       printf (" %d\n",p->index);
3745     }
3746 }
3747 
3748 static int ppi_index;
3749 
3750 /* Take a ppi code, expand all varying fields in it and fill all the
3751    right entries in 'table' with the opcode index.
3752    NOTE: tail recursion optimization removed for simplicity.  */
3753 
3754 static void
3755 expand_ppi_code (int val, int i, const char *s)
3756 {
3757   int j;
3758 
3759   switch (s[0])
3760     {
3761     default:
3762       fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]);
3763       exit (2);
3764       break;
3765     case 'g':
3766     case 'z':
3767       if (warn_conflicts && table[val] != 0)
3768 	conflict_warn (val, i);
3769 
3770       /* The last four bits are disregarded for the switch table.  */
3771       table[val] = i;
3772       return;
3773     case 'm':
3774       /* Four-bit expansion.  */
3775       for (j = 0; j < 16; j++)
3776 	expand_ppi_code ((val << 4) + j, i, s + 4);
3777       break;
3778     case '.':
3779     case '0':
3780       expand_ppi_code ((val << 1), i, s + 1);
3781       break;
3782     case '1':
3783       expand_ppi_code ((val << 1) + 1, i, s + 1);
3784       break;
3785     case 'i':
3786     case 'e': case 'f':
3787     case 'x': case 'y':
3788       expand_ppi_code ((val << 1), i, s + 1);
3789       expand_ppi_code ((val << 1) + 1, i, s + 1);
3790       break;
3791     case 'c':
3792       expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2);
3793       expand_ppi_code ((val << 2) + 2, i, s + 2);
3794       expand_ppi_code ((val << 2) + 3, i, s + 2);
3795       break;
3796     }
3797 }
3798 
3799 static void
3800 ppi_filltable (void)
3801 {
3802   op *p;
3803   ppi_index = 1;
3804 
3805   for (p = ppi_tab; p->name; p++)
3806     {
3807       p->index = ppi_index++;
3808       expand_ppi_code (0, p->index, p->code);
3809     }
3810 }
3811 
3812 static void
3813 ppi_gensim (void)
3814 {
3815   op *p = ppi_tab;
3816 
3817   printf ("#define DSR_MASK_G 0x80\n");
3818   printf ("#define DSR_MASK_Z 0x40\n");
3819   printf ("#define DSR_MASK_N 0x20\n");
3820   printf ("#define DSR_MASK_V 0x10\n");
3821   printf ("\n");
3822   printf ("#define COMPUTE_OVERFLOW do {\\\n");
3823   printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;\\\n");
3824   printf ("  if (overflow && S) \\\n");
3825   printf ("    { \\\n");
3826   printf ("      if (res_grd & 0x80) \\\n");
3827   printf ("        { \\\n");
3828   printf ("          res = 0x80000000;\\\n");
3829   printf ("          res_grd |=  0xff;\\\n");
3830   printf ("        } \\\n");
3831   printf ("      else \\\n");
3832   printf ("        { \\\n");
3833   printf ("          res = 0x7fffffff;\\\n");
3834   printf ("          res_grd &= ~0xff;\\\n");
3835   printf ("        } \\\n");
3836   printf ("      overflow = 0;\\\n");
3837   printf ("    } \\\n");
3838   printf ("} while (0)\n");
3839   printf ("\n");
3840   printf ("#define ADD_SUB_GE \\\n");
3841   printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3842   printf ("\n");
3843   printf ("static void\n");
3844   printf ("ppi_insn (int iword)\n");
3845   printf ("{\n");
3846   printf ("  /* 'ee' = [x0, x1, y0, a1] */\n");
3847   printf ("  static char const e_tab[] = { 8,  9, 10,  5};\n");
3848   printf ("  /* 'ff' = [y0, y1, x0, a1] */\n");
3849   printf ("  static char const f_tab[] = {10, 11,  8,  5};\n");
3850   printf ("  /* 'xx' = [x0, x1, a0, a1]  */\n");
3851   printf ("  static char const x_tab[] = { 8,  9,  7,  5};\n");
3852   printf ("  /* 'yy' = [y0, y1, m0, m1]  */\n");
3853   printf ("  static char const y_tab[] = {10, 11, 12, 14};\n");
3854   printf ("  /* 'gg' = [m0, m1, a0, a1]  */\n");
3855   printf ("  static char const g_tab[] = {12, 14,  7,  5};\n");
3856   printf ("  /* 'uu' = [x0, y0, a0, a1]  */\n");
3857   printf ("  static char const u_tab[] = { 8, 10,  7,  5};\n");
3858   printf ("\n");
3859   printf ("  int z;\n");
3860   printf ("  int res, res_grd;\n");
3861   printf ("  int carry, overflow, greater_equal;\n");
3862   printf ("\n");
3863   printf ("  switch (ppi_table[iword >> 4]) {\n");
3864 
3865   for (; p->name; p++)
3866     {
3867       int shift, j;
3868       int cond = 0;
3869       int havedecl = 0;
3870       const char *s = p->code;
3871 
3872       printf ("  /* %s %s */\n", p->name, p->code);
3873       printf ("  case %d:\n", p->index);
3874 
3875       printf ("    {\n");
3876       for (shift = 16; *s; )
3877 	{
3878 	  switch (*s)
3879 	    {
3880 	    case 'i':
3881 	      printf ("      int i = (iword >> 4) & 0x7f;\n");
3882 	      s += 6;
3883 	      break;
3884 	    case 'e':
3885 	    case 'f':
3886 	    case 'x':
3887 	    case 'y':
3888 	    case 'g':
3889 	    case 'u':
3890 	      shift -= 2;
3891 	      printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
3892 		      *s, *s, shift);
3893 	      havedecl = 1;
3894 	      s += 2;
3895 	      break;
3896 	    case 'c':
3897 	      printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3898 	      printf ("\treturn;\n");
3899 	      printf ("      ATTRIBUTE_FALLTHROUGH;\n");
3900 	      printf ("    }\n");
3901 	      printf ("  case %d:\n", p->index + 1);
3902 	      printf ("    {\n");
3903 	      cond = 1;
3904 	    case '0':
3905 	    case '1':
3906 	    case '.':
3907 	      shift -= 2;
3908 	      s += 2;
3909 	      break;
3910 	    case 'z':
3911 	      if (havedecl)
3912 		printf ("\n");
3913 	      printf ("      z = iword & 0xf;\n");
3914 	      havedecl = 2;
3915 	      s += 4;
3916 	      break;
3917 	    }
3918 	}
3919       if (havedecl == 1)
3920 	printf ("\n");
3921       else if (havedecl == 2)
3922 	printf ("      {\n");
3923       for (j = 0; j < MAX_NR_STUFF; j++)
3924 	{
3925 	  if (p->stuff[j])
3926 	    {
3927 	      if (*p->stuff[j])
3928 		{
3929 		  printf ("      %s%s",
3930 			  (havedecl == 2 ? "  " : ""),
3931 			  p->stuff[j]);
3932 		}
3933 	      printf ("\n");
3934 	    }
3935 	}
3936       if (havedecl == 2)
3937 	printf ("      }\n");
3938       if (cond)
3939 	{
3940 	  printf ("      if (iword & 0x200)\n");
3941 	  printf ("        goto assign_z;\n");
3942 	}
3943       printf ("      break;\n");
3944       printf ("    }\n");
3945     }
3946 
3947   printf ("  default:\n");
3948   printf ("    {\n");
3949   printf ("      RAISE_EXCEPTION (SIGILL);\n");
3950   printf ("      return;\n");
3951   printf ("    }\n");
3952   printf ("  }\n");
3953   printf ("  DSR &= ~0xf1;\n");
3954   printf ("  if (res || res_grd)\n");
3955   printf ("    DSR |= greater_equal | (res_grd >> 2 & DSR_MASK_N) | overflow;\n");
3956   printf ("  else\n");
3957   printf ("    DSR |= DSR_MASK_Z | overflow;\n");
3958   printf (" assign_dc:\n");
3959   printf ("  switch (DSR >> 1 & 7)\n");
3960   printf ("    {\n");
3961   printf ("    case 0: /* Carry Mode */\n");
3962   printf ("      DSR |= carry;\n");
3963   printf ("      break;\n");
3964   printf ("    case 1: /* Negative Value Mode */\n");
3965   printf ("      DSR |= res_grd >> 7 & 1;\n");
3966   printf ("      break;\n");
3967   printf ("    case 2: /* Zero Value Mode */\n");
3968   printf ("      DSR |= DSR >> 6 & 1;\n");
3969   printf ("      break;\n");
3970   printf ("    case 3: /* Overflow mode */\n");
3971   printf ("      DSR |= overflow >> 4;\n");
3972   printf ("      break;\n");
3973   printf ("    case 4: /* Signed Greater Than Mode */\n");
3974   printf ("      DSR |= DSR >> 7 & 1;\n");
3975   printf ("      break;\n");
3976   printf ("    case 5: /* Signed Greater Than Or Equal Mode */\n");
3977   printf ("      DSR |= greater_equal >> 7;\n");
3978   printf ("      break;\n");
3979   printf ("    }\n");
3980   printf (" assign_z:\n");
3981   printf ("  if (0xa05f >> z & 1)\n");
3982   printf ("    {\n");
3983   printf ("      RAISE_EXCEPTION (SIGILL);\n");
3984   printf ("      return;\n");
3985   printf ("    }\n");
3986   printf ("  DSP_R (z) = res;\n");
3987   printf ("  DSP_GRD (z) = res_grd;\n");
3988   printf ("}\n");
3989 }
3990 
3991 int
3992 main (int ac, char *av[])
3993 {
3994   /* Verify the table before anything else.  */
3995   {
3996     op *p;
3997     for (p = tab; p->name; p++)
3998       {
3999 	/* Check that the code field contains 16 bits.  */
4000 	if (strlen (p->code) != 16)
4001 	  {
4002 	    fprintf (stderr, "Code `%s' length wrong (%zu) for `%s'\n",
4003 		     p->code, strlen (p->code), p->name);
4004 	    abort ();
4005 	  }
4006       }
4007   }
4008 
4009   /* Now generate the requested data.  */
4010   if (ac > 1)
4011     {
4012       if (ac > 2 && strcmp (av[2], "-w") == 0)
4013 	{
4014 	  warn_conflicts = 1;
4015 	}
4016       if (strcmp (av[1], "-t") == 0)
4017 	{
4018 	  gengastab ();
4019 	}
4020       else if (strcmp (av[1], "-d") == 0)
4021 	{
4022 	  gendefines ();
4023 	}
4024       else if (strcmp (av[1], "-s") == 0)
4025 	{
4026 	  filltable (tab);
4027 	  dumptable ("sh_jump_table", 1 << 16, 0);
4028 
4029 	  memset (table, 0, sizeof table);
4030 	  filltable (movsxy_tab);
4031 	  expand_ppi_movxy ();
4032 	  dumptable ("sh_dsp_table", 1 << 12, 0xf000);
4033 
4034 	  memset (table, 0, sizeof table);
4035 	  ppi_filltable ();
4036 	  dumptable ("ppi_table", 1 << 12, 0);
4037 	}
4038       else if (strcmp (av[1], "-x") == 0)
4039 	{
4040 	  filltable (tab);
4041 	  filltable (movsxy_tab);
4042 	  gensim ();
4043 	}
4044       else if (strcmp (av[1], "-p") == 0)
4045 	{
4046 	  ppi_filltable ();
4047 	  ppi_gensim ();
4048 	}
4049     }
4050   else
4051     fprintf (stderr, "Opcode table generation no longer supported.\n");
4052   return 0;
4053 }
4054