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