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