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