PE LD: Merge .CRT .ctors and .dtors into .rdata
[binutils-gdb.git] / sim / sh / gencode.c
blob42009fc23e2c43fb59546906142e55dd9c874b78
1 /* Simulator/Opcode generator for the Renesas
2 (formerly Hitachi) / SuperH Inc. Super-H architecture.
4 Written by Steve Chamberlain of Cygnus Support.
5 sac@cygnus.com
7 This file is part of SH sim.
10 THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
22 /* This program generates the opcode table for the assembler and
23 the simulator code.
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
33 #include <ctype.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include "libiberty.h"
40 #define MAX_NR_STUFF 42
42 typedef struct
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;
53 static op tab[] =
56 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
58 "R[n] += SEXT (i);",
59 "if (i == 0) {",
60 " UNDEF(n); /* see #ifdef PARANOID */",
61 " break;",
62 "}",
65 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
67 "R[n] += R[m];",
71 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
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));",
80 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
82 "ult = R[n] + R[m];",
83 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
84 "R[n] = ult;",
88 { "0", "0", "and #<imm>,R0", "11001001i8*1....",
90 "R0 &= i;",
93 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
95 "R[n] &= R[m];",
98 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
100 "MA (1);",
101 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
105 { "", "", "bf <bdisp8>", "10001011i8p1....",
107 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
108 "if (!T) {",
109 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
110 " cycles += 2;",
111 "}",
115 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
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 "}",
126 { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
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. */",
141 { "", "", "bra <bdisp12>", "1010i12.........",
143 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
144 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
145 "cycles += 2;",
146 "Delay_Slot (PC + 2);",
150 { "", "n", "braf <REG_N>", "0000nnnn00100011",
152 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
153 "SET_NIP (PC + 4 + R[n]);",
154 "cycles += 2;",
155 "Delay_Slot (PC + 2);",
159 { "", "", "bsr <bdisp12>", "1011i12.........",
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);",
169 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
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);",
179 { "", "", "bt <bdisp8>", "10001001i8p1....",
181 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
182 "if (T) {",
183 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
184 " cycles += 2;",
185 "}",
189 { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
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);",
201 { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
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));",
210 { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
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 "}",
222 { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
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 "}",
234 { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
236 "if (R[n] < -256 || R[n] > 255) {",
237 " L (n);",
238 " SET_SR_CS (1);",
239 " R[n] = 255;",
240 "}",
243 { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
245 "if (R[n] < -65536 || R[n] > 65535) {",
246 " L (n);",
247 " SET_SR_CS (1);",
248 " R[n] = 65535;",
249 "}",
252 { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
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);",
263 { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
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);",
274 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
276 "R[n] = (R[n] * R0) & 0xffffffff;",
277 "L (n);",
280 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
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);",
290 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
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;",
299 { "", "", "resbank", "0000000001011011",
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 "}",
337 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
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);",
350 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
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);",
364 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
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);",
378 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
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);",
391 { "", "", "nott", "0000000001101000",
393 "SET_SR_T (T == 0);",
397 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
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 "}",
408 { "", "", "clrmac", "0000000000101000",
410 "MACH = 0;",
411 "MACL = 0;",
415 { "", "", "clrs", "0000000001001000",
417 "SET_SR_S (0);",
421 { "", "", "clrt", "0000000000001000",
423 "SET_SR_T (0);",
427 /* sh4a */
428 { "", "", "clrdmxy", "0000000010001000",
430 "saved_state.asregs.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
434 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
436 "SET_SR_T (R0 == SEXT (i));",
439 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
441 "SET_SR_T (R[n] == R[m]);",
444 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
446 "SET_SR_T (R[n] >= R[m]);",
449 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
451 "SET_SR_T (R[n] > R[m]);",
454 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
456 "SET_SR_T (UR[n] > UR[m]);",
459 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
461 "SET_SR_T (UR[n] >= UR[m]);",
464 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
466 "SET_SR_T (R[n] > 0);",
469 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
471 "SET_SR_T (R[n] >= 0);",
474 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
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));",
484 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
486 "SET_SR_Q ((R[n] & sbit) != 0);",
487 "SET_SR_M ((R[m] & sbit) != 0);",
488 "SET_SR_T (M != Q);",
492 { "", "", "div0u", "0000000000011001",
494 "SET_SR_M (0);",
495 "SET_SR_Q (0);",
496 "SET_SR_T (0);",
500 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
502 "div1 (&R0, m, n/*, T*/);",
506 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
508 "dmul_s (R[n], R[m]);",
512 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
514 "dmul_u (R[n], R[m]);",
518 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
520 "R[n]--;",
521 "SET_SR_T (R[n] == 0);",
525 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
527 "R[n] = SEXT (R[m]);",
530 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
532 "R[n] = SEXTW (R[m]);",
536 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
538 "R[n] = (R[m] & 0xff);",
541 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
543 "R[n] = (R[m] & 0xffff);",
547 /* sh2e */
548 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
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);",
561 /* sh2e */
562 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
564 "FP_OP (n, +, m);",
568 /* sh2e */
569 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
571 "FP_CMP (n, ==, m);",
574 /* sh2e */
575 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
577 "FP_CMP (n, >, m);",
581 /* sh4 */
582 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
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 "}",
599 /* sh4 */
600 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
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 "}",
617 /* sh2e */
618 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
620 "FP_OP (n, /, m);",
621 "/* FIXME: check for DP and (n & 1) == 0? */",
625 /* sh4 */
626 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
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 "}",
645 /* sh2e */
646 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
648 "SET_FR (n, (float) 0.0);",
649 "/* FIXME: check for DP and (n & 1) == 0? */",
653 /* sh2e */
654 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
656 "SET_FR (n, (float) 1.0);",
657 "/* FIXME: check for DP and (n & 1) == 0? */",
661 /* sh2e */
662 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
664 " union",
665 " {",
666 " int i;",
667 " float f;",
668 " } u;",
669 " u.f = FR (n);",
670 " FPUL = u.i;",
674 /* sh2e */
675 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
677 /* sh4 */
678 "if (FPSCR_PR)",
679 " SET_DR (n, (double) FPUL);",
680 "else",
681 "{",
682 " SET_FR (n, (float) FPUL);",
683 "}",
687 /* sh2e */
688 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
690 "SET_FR (n, FR (m) * FR (0) + FR (n));",
691 "/* FIXME: check for DP and (n & 1) == 0? */",
695 /* sh2e */
696 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
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 "}",
711 /* sh2e */
712 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
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 "}",
726 /* sh2e */
727 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
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 "}",
741 /* sh2a */
742 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
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);",
755 /* sh2e */
756 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
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 "}",
772 /* sh2e */
773 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
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 "}",
789 /* sh2e */
790 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
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 "}",
804 /* sh2e */
805 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
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 "}",
820 /* sh4:
821 See fmov instructions above for move to/from extended fp registers. */
823 /* sh2e */
824 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
826 "FP_OP (n, *, m);",
830 /* sh2e */
831 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
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);",
844 /* sh4a */
845 { "", "", "fpchg", "1111011111111101",
847 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
851 /* sh4 */
852 { "", "", "frchg", "1111101111111101",
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);",
863 /* sh4 */
864 { "", "", "fsca", "1111eeee11111101",
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 " }",
878 /* sh4 */
879 { "", "", "fschg", "1111001111111101",
881 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
885 /* sh3e */
886 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
888 "FP_UNARY (n, sqrt);",
892 /* sh4 */
893 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
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)));",
904 /* sh2e */
905 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
907 "FP_OP (n, -, m);",
911 /* sh2e */
912 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
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);",
929 /* sh4 */
930 { "", "", "ftrv <FV_N>", "1111vv0111111101",
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 "}",
944 /* sh2e */
945 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
947 " union",
948 " {",
949 " int i;",
950 " float f;",
951 " } u;",
952 " u.i = FPUL;",
953 " SET_FR (n, u.f);",
957 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
959 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
960 "SET_NIP (PT2H (R[n]));",
961 "cycles += 2;",
962 "Delay_Slot (PC + 2);",
966 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
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);",
977 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
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]));",
986 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
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));",
996 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
998 "CREG (m) = R[n];",
999 "/* FIXME: user mode */",
1002 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
1004 "SET_SR (R[n]);",
1005 "/* FIXME: user mode */",
1008 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
1010 "SET_MOD (R[n]);",
1013 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
1015 "if (SR_MD)",
1016 " DBR = R[n]; /* priv mode */",
1017 "else",
1018 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1021 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
1023 "if (SR_MD)",
1024 " SGR = R[n]; /* priv mode */",
1025 "else",
1026 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1029 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
1031 "if (SR_MD)", /* FIXME? */
1032 " TBR = R[n]; /* priv mode */",
1033 "else",
1034 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1037 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
1039 "MA (1);",
1040 "CREG (m) = RLAT (R[n]);",
1041 "R[n] += 4;",
1042 "/* FIXME: user mode */",
1045 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
1047 "MA (1);",
1048 "SET_SR (RLAT (R[n]));",
1049 "R[n] += 4;",
1050 "/* FIXME: user mode */",
1053 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
1055 "MA (1);",
1056 "SET_MOD (RLAT (R[n]));",
1057 "R[n] += 4;",
1060 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
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 */",
1072 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
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 */",
1085 /* sh-dsp */
1086 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
1088 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
1091 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
1093 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
1097 /* sh4a */
1098 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
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;",
1106 { "", "", "ldrc #<imm>", "10001010i8*1....",
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;",
1115 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
1117 "SREG (m) = R[n];",
1120 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
1122 "MA (1);",
1123 "SREG (m) = RLAT (R[n]);",
1124 "R[n] += 4;",
1127 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
1128 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
1130 "SET_FPSCR (R[n]);",
1133 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
1134 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
1136 "MA (1);",
1137 "SET_FPSCR (RLAT (R[n]));",
1138 "R[n] += 4;",
1142 { "", "", "ldtlb", "0000000000111000",
1144 "/* We don't implement cache or tlb, so this is a noop. */",
1148 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
1150 "macl (&R0, memory, n, m);",
1154 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
1156 "macw (&R0, memory, n, m, endianw);",
1160 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
1162 "R[n] = SEXT (i);",
1165 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
1167 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1168 "R[n] = ((i << 24) >> 12) | RIAT (nip);",
1169 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
1172 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
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. */",
1179 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
1181 "R[n] = R[m];",
1185 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
1187 "MA (1);",
1188 "R0 = RSBAT (i + GBR);",
1189 "L (0);",
1192 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
1194 "MA (1);",
1195 "R0 = RSBAT (i + R[m]);",
1196 "L (0);",
1199 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
1201 "MA (1);",
1202 "R[n] = RSBAT (R0 + R[m]);",
1203 "L (n);",
1206 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
1208 "MA (1);",
1209 "R[n] = RSBAT (R[m]);",
1210 "R[m] += 1;",
1211 "L (n);",
1214 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
1216 "MA (1);",
1217 "R[n] -= 1;",
1218 "R0 = RSBAT (R[n]);",
1219 "L (0);",
1222 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
1224 "MA (1);",
1225 "WBAT (R[n], R[m]);",
1228 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
1230 "MA (1);",
1231 "WBAT (i + GBR, R0);",
1234 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
1236 "MA (1);",
1237 "WBAT (i + R[m], R0);",
1240 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
1242 "MA (1);",
1243 "WBAT (R[n] + R0, R[m]);",
1246 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
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);",
1255 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
1257 "MA (1);",
1258 "WBAT (R[n], R0);",
1259 "R[n] += 1;",
1262 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
1264 "MA (1);",
1265 "R[n] = RSBAT (R[m]);",
1266 "L (n);",
1270 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
1272 "MA (1);",
1273 "R0 = RLAT (i + GBR);",
1274 "L (0);",
1277 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
1279 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1280 "MA (1);",
1281 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
1282 "L (n);",
1285 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1287 "MA (1);",
1288 "R[n] = RLAT (i + R[m]);",
1289 "L (n);",
1292 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1294 "MA (1);",
1295 "R[n] = RLAT (R0 + R[m]);",
1296 "L (n);",
1299 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1301 "MA (1);",
1302 "R[n] = RLAT (R[m]);",
1303 "R[m] += 4;",
1304 "L (n);",
1307 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1309 "MA (1);",
1310 "R[n] -= 4;",
1311 "R0 = RLAT (R[n]);",
1312 "L (0);",
1315 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1317 "MA (1);",
1318 "R[n] = RLAT (R[m]);",
1319 "L (n);",
1322 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1324 "MA (1);",
1325 "WLAT (i + GBR, R0);",
1328 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1330 "MA (1);",
1331 "WLAT (i + R[n], R[m]);",
1334 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1336 "MA (1);",
1337 "WLAT (R0 + R[n], R[m]);",
1340 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
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);",
1349 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1351 "MA (1) ;",
1352 "WLAT (R[n], R0);",
1353 "R[n] += 4;",
1356 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1358 "MA (1);",
1359 "WLAT (R[n], R[m]);",
1363 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1365 "MA (1);",
1366 "R0 = RSWAT (i + GBR);",
1367 "L (0);",
1370 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1372 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1373 "MA (1);",
1374 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1375 "L (n);",
1378 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1380 "MA (1);",
1381 "R0 = RSWAT (i + R[m]);",
1382 "L (0);",
1385 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1387 "MA (1);",
1388 "R[n] = RSWAT (R0 + R[m]);",
1389 "L (n);",
1392 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1394 "MA (1);",
1395 "R[n] = RSWAT (R[m]);",
1396 "R[m] += 2;",
1397 "L (n);",
1400 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1402 "MA (1);",
1403 "R[n] -= 2;",
1404 "R0 = RSWAT (R[n]);",
1405 "L (0);",
1408 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1410 "MA (1);",
1411 "R[n] = RSWAT (R[m]);",
1412 "L (n);",
1415 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1417 "MA (1);",
1418 "WWAT (i + GBR, R0);",
1421 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1423 "MA (1);",
1424 "WWAT (i + R[m], R0);",
1427 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1429 "MA (1);",
1430 "WWAT (R0 + R[n], R[m]);",
1433 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
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);",
1442 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1444 "MA (1);",
1445 "WWAT (R[n], R0);",
1446 "R[n] += 2;",
1449 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1451 "MA (1);",
1452 "WWAT (R[n], R[m]);",
1456 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1458 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1459 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1463 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1465 "/* We don't simulate cache, so this insn is identical to mov. */",
1466 "MA (1);",
1467 "WLAT (R[n], R[0]);",
1471 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
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);",
1483 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
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) */",
1494 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1496 "R[n] = T;",
1499 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1501 "R[n] = (T == 0);",
1504 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
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);",
1514 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
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);",
1525 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1527 "MACL = ((int) R[n]) * ((int) R[m]);",
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",
1534 "MACL = R[n] * R[m];",
1537 #endif
1539 /* muls.w - see muls */
1540 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1542 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1546 /* mulu.w - see mulu */
1547 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1549 "MACL = (((unsigned int) (unsigned short) R[n])",
1550 " * ((unsigned int) (unsigned short) R[m]));",
1554 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1556 "R[n] = - R[m];",
1560 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1562 "ult = -T;",
1563 "SET_SR_T (ult > 0);",
1564 "R[n] = ult - R[m];",
1565 "SET_SR_T (T || (R[n] > ult));",
1569 { "", "", "nop", "0000000000001001",
1571 "/* nop */",
1575 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1577 "R[n] = ~R[m];",
1581 /* sh4a */
1582 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1584 "/* Except for the effect on the cache - which is not simulated -",
1585 " this is like a nop. */",
1589 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1591 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1592 "/* FIXME: Cache not implemented */",
1596 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1598 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1599 "/* FIXME: Cache not implemented */",
1603 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1605 "(void) RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1606 "/* FIXME: Cache not implemented */",
1610 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1612 "R0 |= i;",
1615 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1617 "R[n] |= R[m];",
1620 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1622 "MA (1);",
1623 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1627 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1629 "/* Except for the effect on the cache - which is not simulated -",
1630 " this is like a nop. */",
1634 /* sh4a */
1635 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1637 "/* Except for the effect on the cache - which is not simulated -",
1638 " this is like a nop. */",
1642 /* sh4a */
1643 { "", "", "synco", "0000000010101011",
1645 "/* Except for the effect on the pipeline - which is not simulated -",
1646 " this is like a nop. */",
1650 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1652 "ult = R[n] < 0;",
1653 "R[n] = (R[n] << 1) | T;",
1654 "SET_SR_T (ult);",
1658 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1660 "ult = R[n] & 1;",
1661 "R[n] = (UR[n] >> 1) | (T << 31);",
1662 "SET_SR_T (ult);",
1666 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1668 "SET_SR_T (R[n] < 0);",
1669 "R[n] <<= 1;",
1670 "R[n] |= T;",
1674 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1676 "SET_SR_T (R[n] & 1);",
1677 "R[n] = UR[n] >> 1;",
1678 "R[n] |= (T << 31);",
1682 { "", "", "rte", "0000000000101011",
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
1702 { "", "", "rts", "0000000000001011",
1704 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1705 "SET_NIP (PT2H (PR));",
1706 "cycles += 2;",
1707 "Delay_Slot (PC + 2);",
1710 { "", "", "rts/n", "0000000001101011",
1712 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1713 "SET_NIP (PT2H (PR));",
1716 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1718 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1719 "R0 = R[n];",
1720 "L (0);",
1721 "SET_NIP (PT2H (PR));",
1725 /* sh4a */
1726 { "", "", "setdmx", "0000000010011000",
1728 "saved_state.asregs.sr |= SR_MASK_DMX;"
1729 "saved_state.asregs.sr &= ~SR_MASK_DMY;"
1733 /* sh4a */
1734 { "", "", "setdmy", "0000000011001000",
1736 "saved_state.asregs.sr |= SR_MASK_DMY;"
1737 "saved_state.asregs.sr &= ~SR_MASK_DMX;"
1741 /* sh-dsp */
1742 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1744 "SET_RC (R[n]);",
1747 { "", "", "setrc #<imm>", "10000010i8*1....",
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 "}",
1763 { "", "", "sets", "0000000001011000",
1765 "SET_SR_S (1);",
1769 { "", "", "sett", "0000000000011000",
1771 "SET_SR_T (1);",
1775 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1777 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1781 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1783 "SET_SR_T (R[n] < 0);",
1784 "R[n] <<= 1;",
1788 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1790 "SET_SR_T (R[n] & 1);",
1791 "R[n] = R[n] >> 1;",
1795 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1797 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1801 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1803 "SET_SR_T (R[n] < 0);",
1804 "R[n] <<= 1;",
1808 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1810 "R[n] <<= 2;",
1813 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1815 "R[n] <<= 8;",
1818 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1820 "R[n] <<= 16;",
1824 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1826 "SET_SR_T (R[n] & 1);",
1827 "R[n] = UR[n] >> 1;",
1831 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1833 "R[n] = UR[n] >> 2;",
1836 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1838 "R[n] = UR[n] >> 8;",
1841 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1843 "R[n] = UR[n] >> 16;",
1847 { "", "", "sleep", "0000000000011011",
1849 "nip += trap (sd, 0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1853 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1855 "R[n] = CREG (m);",
1859 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1861 "if (SR_MD)",
1862 " R[n] = SGR; /* priv mode */",
1863 "else",
1864 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1867 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1869 "if (SR_MD)",
1870 " R[n] = DBR; /* priv mode */",
1871 "else",
1872 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1875 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1877 "if (SR_MD)", /* FIXME? */
1878 " R[n] = TBR; /* priv mode */",
1879 "else",
1880 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1883 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1885 "MA (1);",
1886 "R[n] -= 4;",
1887 "WLAT (R[n], CREG (m));",
1890 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
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 */",
1902 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
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 */",
1915 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1917 "R[n] = SREG (m);",
1920 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1922 "MA (1);",
1923 "R[n] -= 4;",
1924 "WLAT (R[n], SREG (m));",
1928 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1930 "R[n] -= R[m];",
1934 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
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));",
1943 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1945 "ult = R[n] - R[m];",
1946 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1947 "R[n] = ult;",
1951 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1953 "R[n] = ((R[m] & 0xffff0000)",
1954 " | ((R[m] << 8) & 0xff00)",
1955 " | ((R[m] >> 8) & 0x00ff));",
1958 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1960 "R[n] = (((R[m] << 16) & 0xffff0000)",
1961 " | ((R[m] >> 16) & 0x00ffff));",
1965 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1967 "MA (1);",
1968 "ult = RBAT (R[n]);",
1969 "SET_SR_T (ult == 0);",
1970 "WBAT (R[n],ult|0x80);",
1974 { "0", "", "trapa #<imm>", "11000011i8*1....",
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 "}",
1999 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
2001 "SET_SR_T ((R[n] & R[m]) == 0);",
2004 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
2006 "SET_SR_T ((R0 & i) == 0);",
2009 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
2011 "MA (1);",
2012 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
2016 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
2018 "R0 ^= i;",
2021 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
2023 "R[n] ^= R[m];",
2026 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
2028 "MA (1);",
2029 "ult = RBAT (GBR+R0);",
2030 "ult ^= i;",
2031 "WBAT (GBR + R0, ult);",
2035 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
2037 "R[n] = (((R[n] >> 16) & 0xffff)",
2038 " | ((R[m] << 16) & 0xffff0000));",
2042 #if 0
2043 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
2045 "divl (0, R[n], R[m]);",
2048 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
2050 "divl (0, R[n], R[m]);",
2053 #endif
2058 static op movsxy_tab[] =
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",
2066 "MA (1);",
2067 "R[n] -= 2;",
2068 "DSP_R (m) = RSWAT (R[n]) << 16;",
2069 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2072 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
2074 "MA (1);",
2075 "DSP_R (m) = RSWAT (R[n]) << 16;",
2076 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2079 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
2081 "MA (1);",
2082 "DSP_R (m) = RSWAT (R[n]) << 16;",
2083 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2084 "R[n] += 2;",
2087 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
2089 "MA (1);",
2090 "DSP_R (m) = RSWAT (R[n]) << 16;",
2091 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2092 "R[n] += R[8];",
2095 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
2097 "MA (1);",
2098 "R[n] -= 2;",
2099 "DSP_R (m) = RSWAT (R[n]);",
2102 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
2104 "MA (1);",
2105 "DSP_R (m) = RSWAT (R[n]);",
2108 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
2110 "MA (1);",
2111 "DSP_R (m) = RSWAT (R[n]);",
2112 "R[n] += 2;",
2115 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
2117 "MA (1);",
2118 "DSP_R (m) = RSWAT (R[n]);",
2119 "R[n] += R[8];",
2122 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
2124 "MA (1);",
2125 "R[n] -= 2;",
2126 "WWAT (R[n], DSP_R (m) >> 16);",
2129 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
2131 "MA (1);",
2132 "WWAT (R[n], DSP_R (m) >> 16);",
2135 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
2137 "MA (1);",
2138 "WWAT (R[n], DSP_R (m) >> 16);",
2139 "R[n] += 2;",
2142 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
2144 "MA (1);",
2145 "WWAT (R[n], DSP_R (m) >> 16);",
2146 "R[n] += R[8];",
2149 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
2151 "MA (1);",
2152 "R[n] -= 2;",
2153 "WWAT (R[n], SEXT (DSP_R (m)));",
2156 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
2158 "MA (1);",
2159 "WWAT (R[n], SEXT (DSP_R (m)));",
2162 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
2164 "MA (1);",
2165 "WWAT (R[n], SEXT (DSP_R (m)));",
2166 "R[n] += 2;",
2169 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
2171 "MA (1);",
2172 "WWAT (R[n], SEXT (DSP_R (m)));",
2173 "R[n] += R[8];",
2176 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
2178 "MA (1);",
2179 "R[n] -= 4;",
2180 "DSP_R (m) = RLAT (R[n]);",
2181 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2184 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
2186 "MA (1);",
2187 "DSP_R (m) = RLAT (R[n]);",
2188 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2191 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
2193 "MA (1);",
2194 "DSP_R (m) = RLAT (R[n]);",
2195 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2196 "R[n] += 4;",
2199 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
2201 "MA (1);",
2202 "DSP_R (m) = RLAT (R[n]);",
2203 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
2204 "R[n] += R[8];",
2207 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
2209 "MA (1);",
2210 "R[n] -= 4;",
2211 "WLAT (R[n], DSP_R (m));",
2214 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
2216 "MA (1);",
2217 "WLAT (R[n], DSP_R (m));",
2220 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
2222 "MA (1);",
2223 "WLAT (R[n], DSP_R (m));",
2224 "R[n] += 4;",
2227 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
2229 "MA (1);",
2230 "WLAT (R[n], DSP_R (m));",
2231 "R[n] += R[8];",
2234 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
2236 "MA (1);",
2237 "R[n] -= 4;",
2238 "WLAT (R[n], SEXT (DSP_R (m)));",
2241 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
2243 "MA (1);",
2244 "WLAT (R[n], SEXT (DSP_R (m)));",
2247 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
2249 "MA (1);",
2250 "WLAT (R[n], SEXT (DSP_R (m)));",
2251 "R[n] += 4;",
2254 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
2256 "MA (1);",
2257 "WLAT (R[n], SEXT (DSP_R (m)));",
2258 "R[n] += R[8];",
2261 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
2263 "DSP_R (m) = RSWAT (R[n]) << 16;",
2264 "if (iword & 3)",
2265 " {",
2266 " iword &= 0xfd53; goto top;",
2267 " }",
2270 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
2272 "DSP_R (m) = RLAT (R[n]);",
2275 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
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 " }",
2285 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
2287 "DSP_R (m) = RLAT (R[n]);",
2288 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2291 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
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 " }",
2301 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
2303 "DSP_R (m) = RLAT (R[n]);",
2304 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2307 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
2309 "WWAT (R[n], DSP_R (m) >> 16);",
2310 "if (iword & 3)",
2311 " {",
2312 " iword &= 0xfd53; goto top;",
2313 " }",
2316 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
2318 "WLAT (R[n], DSP_R (m));",
2321 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
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 " }",
2331 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
2333 "WLAT (R[n], DSP_R (m));",
2334 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2337 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
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 " }",
2347 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
2349 "WLAT (R[n], DSP_R (m));",
2350 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
2353 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
2355 "DSP_R (m) = RSWAT (R[n]) << 16;",
2358 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
2360 "DSP_R (m) = RSWAT (R[n]) << 16;",
2361 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2364 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
2366 "DSP_R (m) = RSWAT (R[n]) << 16;",
2367 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2370 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
2372 "WWAT (R[n], DSP_R (m) >> 16);",
2375 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
2377 "WWAT (R[n], DSP_R (m) >> 16);",
2378 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
2381 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
2383 "WWAT (R[n], DSP_R (m) >> 16);",
2384 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2387 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
2389 "DSP_R (m) = RLAT (R[n]);",
2392 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
2394 "DSP_R (m) = RLAT (R[n]);",
2395 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2398 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
2400 "DSP_R (m) = RLAT (R[n]);",
2401 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2404 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
2406 "WLAT (R[n], DSP_R (m));",
2409 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
2411 "WLAT (R[n], DSP_R (m));",
2412 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
2415 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
2417 "WLAT (R[n], DSP_R (m));",
2418 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
2421 { "", "", "nopx nopy", "1111000000000000",
2423 "/* nop */",
2426 { "", "", "ppi", "1111100000000000",
2428 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
2429 "ppi_insn (RIAT (nip));",
2430 "SET_NIP (nip + 2);",
2431 "iword &= 0xf7ff; goto top;",
2434 #endif
2438 static op ppi_tab[] =
2440 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
2442 "int Sz = DSP_R (z) & 0xffff0000;",
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;",
2458 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
2460 "int Sz = DSP_R (z);",
2461 "int Sz_grd = GET_DSP_GRD (z);",
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;",
2502 { "","", "pmuls Se,Sf,Dg", "0100eeff0000gg00",
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;",
2512 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
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);",
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);",
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;",
2533 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
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);",
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);",
2546 "z = u;",
2547 "res = Sx + Sy;",
2548 "carry = (unsigned) res < (unsigned) Sx;",
2549 "res_grd = Sx_grd + Sy_grd + carry;",
2550 "COMPUTE_OVERFLOW;",
2553 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
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);",
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",
2574 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
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);",
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",
2595 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
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);",
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;",
2610 { "","", "pwsb Sx,Sy,Dz", "10100100....zzzz",
2612 "return;",
2615 { "","", "pwad Sx,Sy,Dz", "10110100....zzzz",
2617 "return;",
2620 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
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;",
2640 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
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;",
2660 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2662 "/* FIXME: duplicate code prnd. */",
2663 "int Sx = DSP_R (x);",
2664 "int Sx_grd = GET_DSP_GRD (x);",
2666 "res = (Sx + 0x8000) & 0xffff0000;",
2667 "carry = (unsigned) res < (unsigned) Sx;",
2668 "res_grd = Sx_grd + carry;",
2669 "COMPUTE_OVERFLOW;",
2670 "ADD_SUB_GE;",
2673 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2675 "int Sx = DSP_R (x);",
2676 "int Sx_grd = GET_DSP_GRD (x);",
2678 "res = (Sx + 0x8000) & 0xffff0000;",
2679 "carry = (unsigned) res < (unsigned) Sx;",
2680 "res_grd = Sx_grd + carry;",
2681 "COMPUTE_OVERFLOW;",
2682 "ADD_SUB_GE;",
2686 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
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 " }",
2712 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
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 " }",
2737 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2739 "/* FIXME: duplicate code prnd. */",
2740 "int Sy = DSP_R (y);",
2741 "int Sy_grd = SIGN32 (Sy);",
2743 "res = (Sy + 0x8000) & 0xffff0000;",
2744 "carry = (unsigned) res < (unsigned) Sy;",
2745 "res_grd = Sy_grd + carry;",
2746 "COMPUTE_OVERFLOW;",
2747 "ADD_SUB_GE;",
2750 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2752 "int Sy = DSP_R (y);",
2753 "int Sy_grd = SIGN32 (Sy);",
2755 "res = (Sy + 0x8000) & 0xffff0000;",
2756 "carry = (unsigned) res < (unsigned) Sy;",
2757 "res_grd = Sy_grd + carry;",
2758 "COMPUTE_OVERFLOW;",
2759 "ADD_SUB_GE;",
2762 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2764 "int Sx = DSP_R (x) & 0xffff0000;",
2765 "int Sy = DSP_R (y) >> 16 & 0x7f;",
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;",
2779 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2781 "int Sx = DSP_R (x);",
2782 "int Sx_grd = GET_DSP_GRD (x);",
2783 "int Sy = DSP_R (y) >> 16 & 0x7f;",
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;",
2824 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
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);",
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;",
2838 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
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);",
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;",
2852 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
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);",
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;",
2866 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
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",
2886 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2888 "res = DSP_R (x) ^ DSP_R (y);",
2889 "goto cond_logical;",
2892 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2894 "res = DSP_R (x) | DSP_R (y);",
2895 "goto cond_logical;",
2898 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2900 "int Sx = DSP_R (x);",
2901 "int Sx_grd = GET_DSP_GRD (x);",
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;",
2911 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2913 "int Sx = DSP_R (x);",
2914 "int Sx_grd = GET_DSP_GRD (x);",
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;",
2924 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2926 "int Sy = DSP_R (y);",
2927 "int Sy_grd = SIGN32 (Sy);",
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;",
2937 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2939 "int Sy = DSP_R (y);",
2940 "int Sy_grd = SIGN32 (Sy);",
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;",
2950 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2952 "res = 0;",
2953 "res_grd = 0;",
2954 "carry = 0;",
2955 "overflow = 0;",
2956 "greater_equal = 1;",
2959 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
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! */",
2969 "/* Do clr. */",
2970 "z = u;",
2971 "res = 0;",
2972 "res_grd = 0;",
2973 "goto assign_z;",
2976 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2978 "unsigned Sx = DSP_R (x);",
2979 "int Sx_grd = GET_DSP_GRD (x);",
2980 "int i = 16;",
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;",
3012 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
3014 "unsigned Sy = DSP_R (y);",
3015 "int i = 16;",
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;",
3037 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
3039 "int Sx = DSP_R (x);",
3040 "int Sx_grd = GET_DSP_GRD (x);",
3042 "res = 0 - Sx;",
3043 "carry = res != 0;",
3044 "res_grd = 0 - Sx_grd - carry;",
3045 "COMPUTE_OVERFLOW;",
3046 "ADD_SUB_GE;",
3049 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
3051 "res = DSP_R (x);",
3052 "res_grd = GET_DSP_GRD (x);",
3053 "carry = 0;",
3054 "COMPUTE_OVERFLOW;",
3055 "ADD_SUB_GE;",
3058 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
3060 "int Sy = DSP_R (y);",
3061 "int Sy_grd = SIGN32 (Sy);",
3063 "res = 0 - Sy;",
3064 "carry = res != 0;",
3065 "res_grd = 0 - Sy_grd - carry;",
3066 "COMPUTE_OVERFLOW;",
3067 "ADD_SUB_GE;",
3070 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
3072 "res = DSP_R (y);",
3073 "res_grd = SIGN32 (res);",
3074 "carry = 0;",
3075 "COMPUTE_OVERFLOW;",
3076 "ADD_SUB_GE;",
3079 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
3081 "res = MACH;",
3082 "res_grd = SIGN32 (res);",
3083 "goto assign_z;",
3086 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
3088 "res = MACL;",
3089 "res_grd = SIGN32 (res);",
3090 "goto assign_z;",
3093 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
3095 "if (0xa05f >> z & 1)",
3096 " RAISE_EXCEPTION (SIGILL);",
3097 "else",
3098 " MACH = DSP_R (z);",
3099 "return;",
3102 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
3104 "if (0xa05f >> z & 1)",
3105 " RAISE_EXCEPTION (SIGILL);",
3106 "else",
3107 " MACL = DSP_R (z);",
3108 "return;",
3111 /* sh4a */
3112 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
3114 "int Sx = DSP_R (x);",
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;",
3123 /* sh4a */
3124 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
3126 "int Sy = DSP_R (y);",
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;",
3139 static int
3140 qfunc (const void *va, const void *vb)
3142 const op *a = va;
3143 const op *b = vb;
3144 char bufa[9];
3145 char bufb[9];
3146 int diff;
3148 memcpy (bufa, a->code, 4);
3149 memcpy (bufa + 4, a->code + 12, 4);
3150 bufa[8] = 0;
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;
3161 static void
3162 sorttab (void)
3164 op *p = tab;
3165 int len = 0;
3167 while (p->name)
3169 p++;
3170 len++;
3172 qsort (tab, len, sizeof (*p), qfunc);
3175 static void
3176 gengastab (void)
3178 op *p;
3179 sorttab ();
3180 for (p = tab; p->name; p++)
3182 printf ("%s %-30s\n", p->code, p->name);
3186 static unsigned short table[1 << 16];
3188 static int warn_conflicts = 0;
3190 static void
3191 conflict_warn (int val, int i)
3193 int ix, key;
3194 int j = table[val];
3196 fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
3197 val, i, table[val]);
3199 for (ix = ARRAY_SIZE (tab); ix >= 0; ix--)
3200 if (tab[ix].index == i || tab[ix].index == j)
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'));
3207 if (val >> 12 == key)
3208 fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name);
3211 for (ix = ARRAY_SIZE (movsxy_tab); ix >= 0; ix--)
3212 if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
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'));
3219 if (val >> 12 == key)
3220 fprintf (stderr, " %s -- %s\n",
3221 movsxy_tab[ix].code, movsxy_tab[ix].name);
3224 for (ix = ARRAY_SIZE (ppi_tab); ix >= 0; ix--)
3225 if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
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'));
3232 if (val >> 12 == key)
3233 fprintf (stderr, " %s -- %s\n",
3234 ppi_tab[ix].code, ppi_tab[ix].name);
3238 /* Take an opcode, expand all varying fields in it out and fill all the
3239 right entries in 'table' with the opcode index. */
3241 static void
3242 expand_opcode (int val, int i, const char *s)
3244 if (*s == 0)
3246 if (warn_conflicts && table[val] != 0)
3247 conflict_warn (val, i);
3248 table[val] = i;
3250 else
3252 int j = 0, m = 0;
3254 switch (s[0])
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++)
3283 expand_opcode ((val << 2) | j, i, s + 2);
3284 expand_opcode ((val << 2) | (j + 16), i, s + 2);
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')
3348 /* 2 vector registers. */
3349 for (j = 0; j < 15; j++)
3350 expand_opcode ((val << 4) | j, i, s + 4);
3352 else
3354 /* 1 vector register. */
3355 for (j = 0; j < 4; j += 1)
3356 expand_opcode ((val << 2) | j, i, s + 2);
3358 break;
3363 /* Print the jump table used to index an opcode into a switch
3364 statement entry. */
3366 static void
3367 dumptable (const char *name, int size, int start)
3369 int lump = 256;
3370 int online = 16;
3372 int i = start;
3374 printf ("unsigned short %s[%d] = {\n", name, size);
3375 while (i < start + size)
3377 int j = 0;
3379 printf ("/* 0x%x */\n", i);
3381 while (j < lump)
3383 int k = 0;
3384 while (k < online)
3386 printf ("%2d", table[i + j + k]);
3387 if (j + k < lump)
3388 printf (",");
3390 k++;
3392 j += k;
3393 printf ("\n");
3395 i += j;
3397 printf ("};\n");
3401 static void
3402 filltable (op *p)
3404 static int index = 1;
3406 sorttab ();
3407 for (; p->name; p++)
3409 p->index = index++;
3410 expand_opcode (0, p->index, p->code);
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
3419 expand_ppi_movxy (void)
3421 int i;
3423 for (i = 0xf000; i < 0xf400; i++)
3424 if (table[i])
3425 table[i + 0x800] = table[0xf800];
3428 static void
3429 gensim_caselist (op *p)
3431 for (; p->name; p++)
3433 int j;
3434 int sextbit = -1;
3435 int needm = 0;
3436 int needn = 0;
3437 const char *s = p->code;
3439 printf (" /* %s %s */\n", p->name, p->code);
3440 printf (" case %d:\n", p->index);
3442 printf (" {\n");
3443 while (*s)
3445 switch (*s)
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 */
3484 printf (" int n = (iword & 3) ?\n");
3485 printf (" ((iword >> 9) & 1) + 4 :\n");
3486 printf (" REG_xy ((iword >> 8) & 3);\n");
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 */
3496 printf (" int n = (iword & 0xc) ?\n");
3497 printf (" ((iword >> 8) & 1) + 6 :\n");
3498 printf (" REG_yx ((iword >> 8) & 3);\n");
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 */
3516 printf (" int m = (iword & 3) ?\n");
3517 printf (" ((iword >> 7) & 1) + 8 :\n");
3518 printf (" DSP_xy ((iword >> 6) & 3);\n");
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 */
3527 printf (" int m = (iword & 3) ?\n");
3528 printf (" 7 - ((iword >> 6) & 2) :\n");
3529 printf (" DSP_ax ((iword >> 6) & 3);\n");
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 */
3538 printf (" int m = (iword & 0xc) ?\n");
3539 printf (" ((iword >> 6) & 1) + 10 :\n");
3540 printf (" DSP_yx ((iword >> 6) & 3);\n");
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 */
3549 printf (" int m = (iword & 0xc) ?\n");
3550 printf (" 7 - ((iword >> 5) & 2) :\n");
3551 printf (" DSP_ay ((iword >> 6) & 3);\n");
3553 else
3554 printf (" int m = 7 - ((iword >> 5) & 2);\n");
3555 s += 2;
3556 break;
3558 case 'i':
3559 printf (" int i = (iword & 0x");
3561 switch (s[1])
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;
3580 printf (")");
3582 switch (s[3])
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;
3601 printf (";\n");
3602 s += 4;
3605 if (sextbit > 0)
3607 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3608 sextbit - 1, sextbit - 1);
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");
3619 /* Do the refs. */
3620 const char *r;
3621 for (r = p->refs; *r; r++)
3623 if (*r == 'f') printf (" CREF (15);\n");
3624 if (*r == '-')
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");
3633 if (*r == '+')
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");
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");
3650 printf (" {\n");
3651 for (j = 0; j < MAX_NR_STUFF; j++)
3653 if (p->stuff[j])
3655 printf (" %s\n", p->stuff[j]);
3658 printf (" }\n");
3661 /* Do the defs. */
3662 const char *r;
3663 for (r = p->defs; *r; r++)
3665 if (*r == 'f') printf (" CDEF (15);\n");
3666 if (*r == '-')
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");
3675 if (*r == '+')
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");
3684 if (*r == '0') printf (" CDEF (0);\n");
3685 if (*r == 'n') printf (" CDEF (n);\n");
3686 if (*r == 'm') printf (" CDEF (m);\n");
3690 printf (" break;\n");
3691 printf (" }\n");
3695 static void
3696 gensim (void)
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");
3713 gensim_caselist (tab);
3714 gensim_caselist (movsxy_tab);
3716 printf (" default:\n");
3717 printf (" {\n");
3718 printf (" RAISE_EXCEPTION (SIGILL);\n");
3719 printf (" }\n");
3720 printf (" }\n");
3721 printf ("}\n");
3724 static void
3725 gendefines (void)
3727 op *p;
3728 filltable (tab);
3729 for (p = tab; p->name; p++)
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++;
3744 printf (" %d\n",p->index);
3748 static int ppi_index;
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. */
3754 static void
3755 expand_ppi_code (int val, int i, const char *s)
3757 int j;
3759 switch (s[0])
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);
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;
3799 static void
3800 ppi_filltable (void)
3802 op *p;
3803 ppi_index = 1;
3805 for (p = ppi_tab; p->name; p++)
3807 p->index = ppi_index++;
3808 expand_ppi_code (0, p->index, p->code);
3812 static void
3813 ppi_gensim (void)
3815 op *p = ppi_tab;
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");
3865 for (; p->name; p++)
3867 int shift, j;
3868 int cond = 0;
3869 int havedecl = 0;
3870 const char *s = p->code;
3872 printf (" /* %s %s */\n", p->name, p->code);
3873 printf (" case %d:\n", p->index);
3875 printf (" {\n");
3876 for (shift = 16; *s; )
3878 switch (*s)
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;
3919 if (havedecl == 1)
3920 printf ("\n");
3921 else if (havedecl == 2)
3922 printf (" {\n");
3923 for (j = 0; j < MAX_NR_STUFF; j++)
3925 if (p->stuff[j])
3927 if (*p->stuff[j])
3929 printf (" %s%s",
3930 (havedecl == 2 ? " " : ""),
3931 p->stuff[j]);
3933 printf ("\n");
3936 if (havedecl == 2)
3937 printf (" }\n");
3938 if (cond)
3940 printf (" if (iword & 0x200)\n");
3941 printf (" goto assign_z;\n");
3943 printf (" break;\n");
3944 printf (" }\n");
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");
3992 main (int ac, char *av[])
3994 /* Verify the table before anything else. */
3996 op *p;
3997 for (p = tab; p->name; p++)
3999 /* Check that the code field contains 16 bits. */
4000 if (strlen (p->code) != 16)
4002 fprintf (stderr, "Code `%s' length wrong (%zu) for `%s'\n",
4003 p->code, strlen (p->code), p->name);
4004 abort ();
4009 /* Now generate the requested data. */
4010 if (ac > 1)
4012 if (ac > 2 && strcmp (av[2], "-w") == 0)
4014 warn_conflicts = 1;
4016 if (strcmp (av[1], "-t") == 0)
4018 gengastab ();
4020 else if (strcmp (av[1], "-d") == 0)
4022 gendefines ();
4024 else if (strcmp (av[1], "-s") == 0)
4026 filltable (tab);
4027 dumptable ("sh_jump_table", 1 << 16, 0);
4029 memset (table, 0, sizeof table);
4030 filltable (movsxy_tab);
4031 expand_ppi_movxy ();
4032 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
4034 memset (table, 0, sizeof table);
4035 ppi_filltable ();
4036 dumptable ("ppi_table", 1 << 12, 0);
4038 else if (strcmp (av[1], "-x") == 0)
4040 filltable (tab);
4041 filltable (movsxy_tab);
4042 gensim ();
4044 else if (strcmp (av[1], "-p") == 0)
4046 ppi_filltable ();
4047 ppi_gensim ();
4050 else
4051 fprintf (stderr, "Opcode table generation no longer supported.\n");
4052 return 0;