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