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