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