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