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