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