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