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