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