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