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