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