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