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