* Test case for PR 18452.
[binutils-gdb.git] / sim / sh / gencode.c
blob75a6eae09a8144cfb2cdd26f42e074c37d472c48
1 /* Simulator/Opcode generator for the Hitachi Super-H architecture.
3 Written by Steve Chamberlain of Cygnus Support.
4 sac@cygnus.com
6 This file is part of SH sim
9 THIS SOFTWARE IS NOT COPYRIGHTED
11 Cygnus offers the following for use in the public domain. Cygnus
12 makes no warranty with regard to the software or it's performance
13 and the user accepts the software "AS IS" with all faults.
15 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 /* This program generates the opcode table for the assembler and
22 the simulator code
24 -t prints a pretty table for the assembler manual
25 -s generates the simulator code jump table
26 -d generates a define table
27 -x generates the simulator code switch statement
28 default generates the opcode tables
32 #include <stdio.h>
34 #define MAX_NR_STUFF 20
36 typedef struct
38 char *defs;
39 char *refs;
40 char *name;
41 char *code;
42 char *stuff[MAX_NR_STUFF];
43 int index;
46 op;
49 op tab[] =
52 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
53 "R[n] += SEXT(i);",
54 "if (i == 0) {",
55 " UNDEF(n); /* see #ifdef PARANOID */",
56 " break;",
57 "}",
59 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
60 "R[n] += R[m];",
63 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
64 "ult = R[n] + T;",
65 "SET_SR_T (ult < R[n]);",
66 "R[n] = ult + R[m];",
67 "SET_SR_T (T || (R[n] < ult));",
70 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
71 "ult = R[n] + R[m];",
72 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
73 "R[n] = ult;",
76 { "0", "", "and #<imm>,R0", "11001001i8*1....",
77 "R0 &= i;",
79 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
80 "R[n] &= R[m];",
82 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
83 "MA (1);",
84 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
87 { "", "", "bf <bdisp8>", "10001011i8p1....",
88 "if (!T) {",
89 " nia = PC + 4 + (SEXT(i) * 2);",
90 " cycles += 2;",
91 "}",
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95 "if (!T) {",
96 " nia = PC + 4 + (SEXT (i) * 2);",
97 " cycles += 2;",
98 " Delay_Slot (PC + 2);",
99 "}",
102 { "", "", "bra <bdisp12>", "1010i12.........",
103 "nia = PC + 4 + (SEXT12 (i) * 2);",
104 "Delay_Slot (PC + 2);",
107 { "", "n", "braf <REG_N>", "0000nnnn00100011",
108 "nia = PC + 4 + R[n];",
109 "Delay_Slot (PC + 2);",
112 { "", "", "bsr <bdisp12>", "1011i12.........",
113 "PR = PC + 4;",
114 "nia = PC + 4 + (SEXT12 (i) * 2);",
115 "Delay_Slot (PC + 2);",
118 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
119 "PR = PC + 4;",
120 "nia = PC + 4 + R[n];",
121 "Delay_Slot (PC + 2);",
124 { "", "", "bt <bdisp8>", "10001001i8p1....",
125 "if (T) {",
126 " nia = PC + 4 + (SEXT (i) * 2);",
127 " cycles += 2;",
128 "}",
131 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
132 "if (T) {",
133 " nia = PC + 4 + (SEXT (i) * 2);",
134 " cycles += 2;",
135 " Delay_Slot (PC + 2);",
136 "}",
139 { "", "", "clrmac", "0000000000101000",
140 "MACH = 0;",
141 "MACL = 0;",
144 { "", "", "clrs", "0000000001001000",
145 "SET_SR_S (0);",
148 { "", "", "clrt", "0000000000001000",
149 "SET_SR_T (0);",
152 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
153 "SET_SR_T (R0 == SEXT (i));",
155 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
156 "SET_SR_T (R[n] == R[m]);",
158 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
159 "SET_SR_T (R[n] >= R[m]);",
161 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
162 "SET_SR_T (R[n] > R[m]);",
164 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
165 "SET_SR_T (UR[n] > UR[m]);",
167 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
168 "SET_SR_T (UR[n] >= UR[m]);",
170 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
171 "SET_SR_T (R[n] > 0);",
173 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
174 "SET_SR_T (R[n] >= 0);",
176 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
177 "ult = R[n] ^ R[m];",
178 "SET_SR_T (((ult & 0xff000000) == 0)",
179 " | ((ult & 0xff0000) == 0)",
180 " | ((ult & 0xff00) == 0)",
181 " | ((ult & 0xff) == 0));",
184 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
185 "SET_SR_Q ((R[n] & sbit) != 0);",
186 "SET_SR_M ((R[m] & sbit) != 0);",
187 "SET_SR_T (M != Q);",
190 { "", "", "div0u", "0000000000011001",
191 "SET_SR_M (0);",
192 "SET_SR_Q (0);",
193 "SET_SR_T (0);",
196 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
197 "div1 (R, m, n/*, T*/);",
200 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
201 "dmul (1/*signed*/, R[n], R[m]);",
204 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
205 "dmul (0/*unsigned*/, R[n], R[m]);",
208 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
209 "R[n]--;",
210 "SET_SR_T (R[n] == 0);",
213 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
214 "R[n] = SEXT (R[m]);",
216 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
217 "R[n] = SEXTW (R[m]);",
220 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
221 "R[n] = (R[m] & 0xff);",
223 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
224 "R[n] = (R[m] & 0xffff);",
227 /* sh3e */
228 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
229 "FP_UNARY (n, fabs);",
230 "/* FIXME: FR(n) &= 0x7fffffff; */",
233 /* sh3e */
234 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
235 "FP_OP (n, +, m);",
238 /* sh3e */
239 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
240 "FP_CMP (n, ==, m);",
242 /* sh3e */
243 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
244 "FP_CMP (n, >, m);",
247 /* start-sanitize-sh4 */
248 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
249 "if (! FPSCR_PR || n & 1)",
250 " saved_state.asregs.exception = SIGILL;",
251 "else",
252 "{",
253 " char buf[4];",
254 " *(float *)buf = DR(n);",
255 " FPUL = *(int *)buf;",
256 "}",
258 /* end-sanitize-sh4 */
260 /* start-sanitize-sh4 */
261 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
262 "if (! FPSCR_PR || n & 1)",
263 " saved_state.asregs.exception = SIGILL;",
264 "else",
265 "{",
266 " char buf[4];",
267 " *(int *)buf = FPUL;",
268 " SET_DR(n, *(float *)buf);",
269 "}",
271 /* end-sanitize-sh4 */
273 /* sh3e */
274 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
275 "FP_OP (n, /, m);",
276 "/* FIXME: check for DP and (n & 1) == 0? */",
279 /* start-sanitize-sh4 */
280 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
281 "/* FIXME: not implemented */",
282 "saved_state.asregs.exception = SIGILL;",
283 "/* FIXME: check for DP and (n & 1) == 0? */",
285 /* end-sanitize-sh4 */
287 /* sh3e */
288 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
289 "SET_FR (n, (float)0.0);",
290 "/* FIXME: check for DP and (n & 1) == 0? */",
293 /* sh3e */
294 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
295 "SET_FR (n, (float)1.0);",
296 "/* FIXME: check for DP and (n & 1) == 0? */",
299 /* sh3e */
300 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
301 "char buf[4];",
302 "*(float *)buf = FR(n);",
303 "FPUL = *(int *)buf;",
306 /* sh3e */
307 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
308 /* start-sanitize-sh4 */
309 "if (FPSCR_PR)",
310 " SET_DR (n, (double)FPUL);",
311 "else",
312 /* end-sanitize-sh4 */
313 "{",
314 " SET_FR (n, (float)FPUL);",
315 "}",
318 /* sh3e */
319 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
320 "SET_FR (n, FR(m) * FR(0) + FR(n));",
321 "/* FIXME: check for DP and (n & 1) == 0? */",
324 /* sh3e */
325 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
326 /* start-sanitize-sh4 */
327 "if (FPSCR_SZ) {",
328 " int ni = XD_TO_XF (n);",
329 " int mi = XD_TO_XF (m);",
330 " SET_XF (ni + 0, XF (mi + 0));",
331 " SET_XF (ni + 1, XF (mi + 1));",
332 "}",
333 "else",
334 /* end-sanitize-sh4 */
335 "{",
336 " SET_FR (n, FR (m));",
337 "}",
339 /* sh3e */
340 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
341 /* start-sanitize-sh4 */
342 "if (FPSCR_SZ) {",
343 " MA (2);",
344 " WDAT (R[n], m);",
345 "}",
346 "else",
347 /* end-sanitize-sh4 */
348 "{",
349 " MA (1);",
350 " WLAT (R[n], FI(m));",
351 "}",
353 /* sh3e */
354 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
355 /* start-sanitize-sh4 */
356 "if (FPSCR_SZ) {",
357 " MA (2);",
358 " RDAT (R[m], n);",
359 "}",
360 "else",
361 /* end-sanitize-sh4 */
362 "{",
363 " MA (1);",
364 " SET_FI(n, RLAT(R[m]));",
365 "}",
367 /* sh3e */
368 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
369 /* start-sanitize-sh4 */
370 "if (FPSCR_SZ) {",
371 " MA (2);",
372 " RDAT (R[m], n);",
373 " R[m] += 8;",
374 "}",
375 "else",
376 /* end-sanitize-sh4 */
377 "{",
378 " MA (1);",
379 " SET_FI (n, RLAT (R[m]));",
380 " R[m] += 4;",
381 "}",
383 /* sh3e */
384 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
385 /* start-sanitize-sh4 */
386 "if (FPSCR_SZ) {",
387 " MA (2);",
388 " R[n] -= 8;",
389 " WDAT (R[n], m);",
390 "}",
391 "else",
392 /* end-sanitize-sh4 */
393 "{",
394 " MA (1);",
395 " R[n] -= 4;",
396 " WLAT (R[n], FI(m));",
397 "}",
399 /* sh3e */
400 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
401 /* start-sanitize-sh4 */
402 "if (FPSCR_SZ) {",
403 " MA (2);",
404 " RDAT (R[0]+R[m], n);",
405 "}",
406 "else",
407 /* end-sanitize-sh4 */
408 "{",
409 " MA (1);",
410 " SET_FI(n, RLAT(R[0] + R[m]));",
411 "}",
413 /* sh3e */
414 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
415 /* start-sanitize-sh4 */
416 "if (FPSCR_SZ) {",
417 " MA (2);",
418 " WDAT (R[0]+R[n], m);",
419 "}",
420 "else",
421 /* end-sanitize-sh4 */
422 "{",
423 " MA (1);",
424 " WLAT((R[0]+R[n]), FI(m));",
425 "}",
428 /* start-sanitize-sh4 */
429 /* See fmov instructions above for move to/from extended fp
430 registers */
431 /* end-sanitize-sh4 */
433 /* sh3e */
434 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
435 "FP_OP(n, *, m);",
438 /* sh3e */
439 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
440 "FP_UNARY(n, -);",
443 /* start-sanitize-sh4 */
444 { "", "", "frchg", "1111101111111101",
445 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
447 /* end-sanitize-sh4 */
449 /* start-sanitize-sh4 */
450 { "", "", "fschg", "1111001111111101",
451 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
453 /* end-sanitize-sh4 */
455 /* sh3e */
456 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
457 "FP_UNARY(n, sqrt);",
460 /* sh3e */
461 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
462 "FP_OP(n, -, m);",
465 /* sh3e */
466 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
467 /* start-sanitize-sh4 */
468 "if (FPSCR_PR) {",
469 " if (DR(n) != DR(n)) /* NaN */",
470 " FPUL = 0x80000000;",
471 " else",
472 " FPUL = (int)DR(n);",
473 "}",
474 "else",
475 /* end-sanitize-sh4 */
476 "if (FR(n) != FR(n)) /* NaN */",
477 " FPUL = 0x80000000;",
478 "else",
479 " FPUL = (int)FR(n);",
482 /* start-sanitize-sh4 */
483 #if 0
484 /* ftst/nan would appear to have been dropped */
485 /* end-sanitize-sh4 */
486 /* sh3e */
487 { "", "", "ftst/nan <FREG_N>", "1111nnnn01111101",
488 "SET_SR_T (isnan (FR(n)));",
490 /* start-sanitize-sh4 */
491 #endif
492 /* end-sanitize-sh4 */
494 /* sh3e */
495 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
496 "char buf[4];",
497 "*(int *)buf = FPUL;",
498 "SET_FR (n, *(float *)buf);",
501 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
502 "nia = R[n];",
503 "Delay_Slot (PC + 2);",
506 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
507 "PR = PC + 4;",
508 "nia = R[n];",
509 "if (~doprofile)",
510 " gotcall (PR, nia);",
511 "Delay_Slot (PC + 2);",
514 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
515 "GBR = R[n];",
516 "/* FIXME: user mode */",
518 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
519 "SET_SR (R[n]);",
520 "/* FIXME: user mode */",
522 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
523 "VBR = R[n];",
524 "/* FIXME: user mode */",
526 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
527 "SSR = R[n];",
528 "/* FIXME: user mode */",
530 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
531 "SPC = R[n];",
532 "/* FIXME: user mode */",
534 /* start-sanitize-sh4 */
535 #if 0
536 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
537 "DBR = R[n];",
538 "/* FIXME: user mode */",
540 #endif
541 /* end-sanitize-sh4 */
542 { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
543 "SET_Rn_BANK (0, R[n]);",
544 "/* FIXME: user mode */",
546 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
547 "SET_Rn_BANK (1, R[n]);",
548 "/* FIXME: user mode */",
550 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
551 "SET_Rn_BANK (2, R[n]);",
552 "/* FIXME: user mode */",
554 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
555 "SET_Rn_BANK (3, R[n]);",
556 "/* FIXME: user mode */",
558 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
559 "SET_Rn_BANK (4, R[n]);",
560 "/* FIXME: user mode */",
562 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
563 "SET_Rn_BANK (5, R[n]);",
564 "/* FIXME: user mode */",
566 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
567 "SET_Rn_BANK (6, R[n]);",
568 "/* FIXME: user mode */",
570 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
571 "SET_Rn_BANK (7, R[n]);",
572 "/* FIXME: user mode */",
574 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
575 "MA (1);",
576 "GBR = RLAT (R[n]);",
577 "R[n] += 4;",
578 "/* FIXME: user mode */",
580 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
581 "MA (1);",
582 "SET_SR (RLAT (R[n]));",
583 "R[n] += 4;",
584 "/* FIXME: user mode */",
586 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
587 "MA (1);",
588 "VBR = RLAT (R[n]);",
589 "R[n] += 4;",
590 "/* FIXME: user mode */",
592 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
593 "MA (1);",
594 "SSR = RLAT (R[n]);",
595 "R[n] += 4;",
596 "/* FIXME: user mode */",
598 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
599 "MA (1);",
600 "SPC = RLAT (R[n]);",
601 "R[n] += 4;",
602 "/* FIXME: user mode */",
604 /* start-sanitize-sh4 */
605 #if 0
606 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
607 "MA (1);",
608 "DBR = RLAT (R[n]);",
609 "R[n] += 4;",
610 "/* FIXME: user mode */",
612 #endif
613 /* end-sanitize-sh4 */
614 { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
615 "MA (1);",
616 "SET_Rn_BANK (0, RLAT (R[n]));",
617 "R[n] += 4;",
618 "/* FIXME: user mode */",
620 { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
621 "MA (1);",
622 "SET_Rn_BANK (1, RLAT (R[n]));",
623 "R[n] += 4;",
624 "/* FIXME: user mode */",
626 { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
627 "MA (1);",
628 "SET_Rn_BANK (2, RLAT (R[n]));",
629 "R[n] += 4;",
630 "/* FIXME: user mode */",
632 { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
633 "MA (1);",
634 "SET_Rn_BANK (3, RLAT (R[n]));",
635 "R[n] += 4;",
636 "/* FIXME: user mode */",
638 { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
639 "MA (1);",
640 "SET_Rn_BANK (4, RLAT (R[n]));",
641 "R[n] += 4;",
642 "/* FIXME: user mode */",
644 { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
645 "MA (1);",
646 "SET_Rn_BANK (5, RLAT (R[n]));",
647 "R[n] += 4;",
648 "/* FIXME: user mode */",
650 { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
651 "MA (1);",
652 "SET_Rn_BANK (6, RLAT (R[n]));",
653 "R[n] += 4;",
654 "/* FIXME: user mode */",
656 { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
657 "MA (1);",
658 "SET_Rn_BANK (7, RLAT (R[n]));",
659 "R[n] += 4;",
660 "/* FIXME: user mode */",
663 /* sh3e */
664 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
665 "FPUL = R[n];",
667 /* sh3e */
668 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
669 "MA (1);",
670 "FPUL = RLAT(R[n]);",
671 "R[n] += 4;",
673 /* sh3e */
674 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
675 "SET_FPSCR(R[n]);",
677 /* sh3e */
678 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
679 "MA (1);",
680 "SET_FPSCR (RLAT(R[n]));",
681 "R[n] += 4;",
684 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
685 "MACH = R[n];",
687 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
688 "MACL= R[n];",
690 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
691 "PR = R[n];",
693 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
694 "MA (1);",
695 "MACH = SEXT(RLAT(R[n]));",
696 "R[n]+=4;",
698 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
699 "MA (1);",
700 "MACL = RLAT(R[n]);",
701 "R[n]+=4;",
703 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
704 "MA (1);",
705 "PR = RLAT(R[n]);",
706 "R[n]+=4;;",
709 { "", "", "ldtlb", "0000000000111000",
710 "/* FIXME: XXX*/ abort();",
713 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
714 "trap (255,R0,memory,maskl,maskw,little_endian);",
715 "/* FIXME: mac.l support */",
718 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
719 "macw(R0,memory,n,m);",
722 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
723 "R[n] = SEXT(i);",
725 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
726 "R[n] = R[m];",
729 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
730 "MA (1);",
731 "R0 = RSBAT (i + GBR);",
732 "L (0);",
734 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
735 "MA (1);",
736 "R0 = RSBAT (i + R[m]);",
737 "L (0);",
739 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
740 "MA (1);",
741 "R[n] = RSBAT (R0 + R[m]);",
742 "L (n);",
744 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
745 "MA (1);",
746 "R[n] = RSBAT (R[m]);",
747 "R[m] += 1;",
748 "L (n);",
750 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
751 "MA (1);",
752 "WBAT (R[n], R[m]);",
754 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
755 "MA (1);",
756 "WBAT (i + GBR, R0);",
758 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
759 "MA (1);",
760 "WBAT (i + R[m], R0);",
762 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
763 "MA (1);",
764 "WBAT (R[n] + R0, R[m]);",
766 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
767 "MA (1);",
768 "R[n] -= 1;",
769 "WBAT (R[n], R[m]);",
771 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
772 "MA (1);",
773 "R[n] = RSBAT (R[m]);",
774 "L (n);",
777 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
778 "MA (1);",
779 "R0 = RLAT (i + GBR);",
780 "L (0);",
782 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
783 "MA (1);",
784 "R[n] = RLAT((PC & ~3) + 4 + i);",
785 "L (n);",
787 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
788 "MA (1);",
789 "R[n] = RLAT (i + R[m]);",
790 "L (n);",
792 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
793 "MA (1);",
794 "R[n] = RLAT (R0 + R[m]);",
795 "L (n);",
797 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
798 "MA (1);",
799 "R[n] = RLAT (R[m]);",
800 "R[m] += 4;",
801 "L (n);",
803 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
804 "MA (1);",
805 "R[n] = RLAT (R[m]);",
806 "L (n);",
808 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
809 "MA (1);",
810 "WLAT (i + GBR, R0);",
812 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
813 "MA (1);",
814 "WLAT (i + R[n], R[m]);",
816 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
817 "MA (1);",
818 "WLAT (R0 + R[n], R[m]);",
820 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
821 "MA (1) ;",
822 "R[n] -= 4;",
823 "WLAT (R[n], R[m]);",
825 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
826 "MA (1);",
827 "WLAT (R[n], R[m]);",
830 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
831 "MA (1)",
832 ";R0 = RSWAT (i + GBR);",
833 "L (0);",
835 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
836 "MA (1);",
837 "R[n] = RSWAT (PC + 4 + i);",
838 "L (n);",
840 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
841 "MA (1);",
842 "R0 = RSWAT (i + R[m]);",
843 "L (0);",
845 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
846 "MA (1);",
847 "R[n] = RSWAT (R0 + R[m]);",
848 "L (n);",
850 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
851 "MA (1);",
852 "R[n] = RSWAT (R[m]);",
853 "R[m] += 2;",
854 "L (n);",
856 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
857 "MA (1);",
858 "R[n] = RSWAT (R[m]);",
859 "L (n);",
861 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
862 "MA (1);",
863 "WWAT (i + GBR, R0);",
865 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
866 "MA (1);",
867 "WWAT (i + R[m], R0);",
869 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
870 "MA (1);",
871 "WWAT (R0 + R[n], R[m]);",
873 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
874 "MA (1);",
875 "R[n] -= 2;",
876 "WWAT (R[n], R[m]);",
878 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
879 "MA (1);",
880 "WWAT (R[n], R[m]);",
883 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
884 "R0 = ((i + 4 + PC) & ~0x3);",
887 /* start-sanitize-sh4 */
888 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
889 "/* FIXME: Not implemented */",
890 "saved_state.asregs.exception = SIGILL;",
892 /* end-sanitize-sh4 */
894 { "n", "", "movt <REG_N>", "0000nnnn00101001",
895 "R[n] = T;",
898 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
899 "MACL = ((int)R[n]) * ((int)R[m]);",
901 #if 0
902 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
903 "MACL = R[n] * R[m];",
905 #endif
907 /* muls.w - see muls */
908 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
909 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
912 /* mulu.w - see mulu */
913 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
914 "MACL = (((unsigned int)(unsigned short)R[n])",
915 " * ((unsigned int)(unsigned short)R[m]));",
918 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
919 "R[n] = - R[m];",
922 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
923 "ult = -T;",
924 "SET_SR_T (ult > 0);",
925 "R[n] = ult - R[m];",
926 "SET_SR_T (T || (R[n] > ult));",
929 { "", "", "nop", "0000000000001001",
930 "/* nop */",
933 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
934 "R[n] = ~R[m];",
937 /* start-sanitize-sh4 */
938 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
939 "/* FIXME: Not implemented */",
940 "saved_state.asregs.exception = SIGILL;",
942 /* end-sanitize-sh4 */
944 /* start-sanitize-sh4 */
945 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
946 "/* FIXME: Not implemented */",
947 "saved_state.asregs.exception = SIGILL;",
949 /* end-sanitize-sh4 */
951 /* start-sanitize-sh4 */
952 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
953 "RSBAT (R[n]); /* Take exceptions like byte load. */",
954 "/* FIXME: Cache not implemented */",
956 /* end-sanitize-sh4 */
958 { "0", "", "or #<imm>,R0", "11001011i8*1....",
959 "R0 |= i;",
961 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
962 "R[n] |= R[m];",
964 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
965 "MA (1);",
966 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
969 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
970 "/* Except for the effect on the cache - which is not simulated -",
971 " this is like a nop. */",
974 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
975 "ult = R[n] < 0;",
976 "R[n] = (R[n] << 1) | T;",
977 "SET_SR_T (ult);",
980 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
981 "ult = R[n] & 1;",
982 "R[n] = (UR[n] >> 1) | (T << 31);",
983 "SET_SR_T (ult);",
986 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
987 "SET_SR_T (R[n] < 0);",
988 "R[n] <<= 1;",
989 "R[n] |= T;",
992 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
993 "SET_SR_T (R[n] & 1);",
994 "R[n] = UR[n] >> 1;",
995 "R[n] |= (T << 31);",
998 { "", "", "rte", "0000000000101011",
999 #if 0
1000 /* SH-[12] */
1001 "int tmp = PC;",
1002 "nia = RLAT (R[15]) + 2;",
1003 "R[15] += 4;",
1004 "SET_SR (RLAT (R[15]) & 0x3f3);",
1005 "R[15] += 4;",
1006 "Delay_Slot (PC + 2);",
1007 #else
1008 "nia = SPC;",
1009 "SET_SR (SSR);",
1010 "Delay_Slot (PC + 2);",
1011 #endif
1014 { "", "", "rts", "0000000000001011",
1015 "nia = PR;",
1016 "Delay_Slot (PC + 2);",
1019 { "", "", "sets", "0000000001011000",
1020 "SET_SR_S (1);",
1023 { "", "", "sett", "0000000000011000",
1024 "SET_SR_T (1);",
1027 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1028 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
1031 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1032 "SET_SR_T (R[n] < 0);",
1033 "R[n] <<= 1;",
1036 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1037 "SET_SR_T (R[n] & 1);",
1038 "R[n] = R[n] >> 1;",
1041 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1042 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
1045 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1046 "SET_SR_T (R[n] < 0);",
1047 "R[n] <<= 1;",
1050 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1051 "R[n] <<= 2;",
1053 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1054 "R[n] <<= 8;",
1056 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1057 "R[n] <<= 16;",
1060 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1061 "SET_SR_T (R[n] & 1);",
1062 "R[n] = UR[n] >> 1;",
1065 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1066 "R[n] = UR[n] >> 2;",
1068 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1069 "R[n] = UR[n] >> 8;",
1071 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1072 "R[n] = UR[n] >> 16;",
1075 { "", "", "sleep", "0000000000011011",
1076 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
1077 "nia = PC;",
1080 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
1081 "R[n] = GBR;",
1083 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
1084 "R[n] = GET_SR ();",
1086 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
1087 "R[n] = VBR;",
1089 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
1090 "R[n] = SSR;",
1092 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
1093 "R[n] = SPC;",
1095 /* start-sanitize-sh4 */
1096 #if 0
1097 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1098 "R[n] = SGR;",
1100 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1101 "R[n] = DBR;",
1103 #endif
1104 /* end-sanitize-sh4 */
1105 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
1106 "R[n] = Rn_BANK (0);",
1108 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
1109 "R[n] = Rn_BANK (1);",
1111 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
1112 "R[n] = Rn_BANK (2);",
1114 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
1115 "R[n] = Rn_BANK (3);",
1117 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
1118 "R[n] = Rn_BANK (4);",
1120 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
1121 "R[n] = Rn_BANK (5);",
1123 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
1124 "R[n] = Rn_BANK (6);",
1126 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
1127 "R[n] = Rn_BANK (7);",
1129 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
1130 "MA (1);",
1131 "R[n] -= 4;",
1132 "WLAT (R[n], GBR);;",
1134 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
1135 "MA (1);",
1136 "R[n] -= 4;",
1137 "WLAT (R[n], GET_SR());",
1139 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
1140 "MA (1);",
1141 "R[n] -= 4;",
1142 "WLAT (R[n], VBR);",
1144 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
1145 "MA (1);",
1146 "R[n] -= 4;",
1147 "WLAT (R[n], SSR);",
1149 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
1150 "MA (1);",
1151 "R[n] -= 4;",
1152 "WLAT (R[n], SPC);",
1154 /* start-sanitize-sh4 */
1155 #if 0
1156 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1157 "MA (1);",
1158 "R[n] -= 4;",
1159 "WLAT (R[n], SGR);",
1161 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1162 "MA (1);",
1163 "R[n] -= 4;",
1164 "WLAT (R[n], DBR);",
1166 #endif
1167 /* end-sanitize-sh4 */
1168 { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
1169 "MA (1);",
1170 "R[n] -= 4;",
1171 "WLAT (R[n], Rn_BANK (0));",
1173 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
1174 "MA (1);",
1175 "R[n] -= 4;",
1176 "WLAT (R[n], Rn_BANK (1));",
1178 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
1179 "MA (1);",
1180 "R[n] -= 4;",
1181 "WLAT (R[n], Rn_BANK (2));",
1183 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
1184 "MA (1);",
1185 "R[n] -= 4;",
1186 "WLAT (R[n], Rn_BANK (3));",
1188 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
1189 "MA (1);",
1190 "R[n] -= 4;",
1191 "WLAT (R[n], Rn_BANK (4));",
1193 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
1194 "MA (1);",
1195 "R[n] -= 4;",
1196 "WLAT (R[n], Rn_BANK (5));",
1198 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1199 "MA (1);",
1200 "R[n] -= 4;",
1201 "WLAT (R[n], Rn_BANK (6));",
1203 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1204 "MA (1);",
1205 "R[n] -= 4;",
1206 "WLAT (R[n], Rn_BANK (7));",
1209 /* sh3e */
1210 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1211 "R[n] = FPUL;",
1213 /* sh3e */
1214 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1215 "MA (1);",
1216 "R[n] -= 4;",
1217 "WLAT (R[n], FPUL);",
1219 /* sh3e */
1220 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1221 "R[n] = GET_FPSCR ();",
1223 /* sh3e */
1224 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1225 "MA (1);",
1226 "R[n] -= 4;",
1227 "WLAT (R[n], GET_FPSCR ());",
1230 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1231 "R[n] = MACH;",
1233 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1234 "R[n] = MACL;",
1236 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1237 "R[n] = PR;",
1239 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1240 "MA (1);",
1241 "R[n] -= 4;",
1242 "WLAT (R[n], MACH);",
1244 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1245 "MA (1);",
1246 "R[n] -= 4;",
1247 "WLAT (R[n], MACL);",
1249 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1250 "MA (1);",
1251 "R[n] -= 4;",
1252 "WLAT (R[n], PR);",
1255 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1256 "R[n] -= R[m];",
1259 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1260 "ult = R[n] - T;",
1261 "SET_SR_T (ult > R[n]);",
1262 "R[n] = ult - R[m];",
1263 "SET_SR_T (T || (R[n] > ult));",
1266 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1267 "ult = R[n] - R[m];",
1268 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1269 "R[n] = ult;",
1272 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1273 "R[n] = ((R[m] & 0xffff0000)",
1274 " | ((R[m] << 8) & 0xff00)",
1275 " | ((R[m] >> 8) & 0x00ff));",
1277 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1278 "R[n] = (((R[m] << 16) & 0xffff0000)",
1279 " | ((R[m] >> 16) & 0x00ffff));",
1282 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1283 "MA (1);",
1284 "ult = RBAT(R[n]);",
1285 "SET_SR_T (ult == 0);",
1286 "WBAT(R[n],ult|0x80);",
1289 { "0", "", "trapa #<imm>", "11000011i8*1....",
1290 #if 0
1291 /* SH-[12] */
1292 "long imm = 0xff & i;",
1293 "if (i==0xc3)",
1294 " PC-=2;",
1295 "if (i<20||i==34||i==0xc3)",
1296 " trap(i,R,memory,maskl,maskw,little_endian);",
1297 "else {",
1298 " R[15]-=4;",
1299 " WLAT(R[15],GET_SR());",
1300 " R[15]-=4;",
1301 " WLAT(R[15],PC+2);",
1302 " PC=RLAT(VBR+(imm<<2))-2;",
1303 "}",
1304 #else
1305 "if (i == 0xc3)",
1306 " {",
1307 " nia = PC;",
1308 " trap (i, R, memory, maskl, maskw, little_endian);",
1309 " }",
1310 "else if (i < 20 || i==34 || i==0xc3)",
1311 " trap (i, R, memory, maskl, maskw, little_endian);",
1312 "else if (!SR_BL) {",
1313 " /* FIXME: TRA = (imm << 2); */",
1314 " SSR = GET_SR();",
1315 " SPC = PC + 2;",
1316 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1317 " /* FIXME: EXPEVT = 0x00000160; */",
1318 " nia = VBR + 0x00000100;",
1319 "}",
1320 #endif
1323 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1324 "SET_SR_T ((R[n] & R[m]) == 0);",
1326 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1327 "SET_SR_T ((R0 & i) == 0);",
1329 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1330 "MA (1);",
1331 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1334 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1335 "R0 ^= i;",
1337 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1338 "R[n] ^= R[m];",
1340 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1341 "MA (1);",
1342 "ult = RBAT (GBR+R0);",
1343 "ult ^= i;",
1344 "WBAT (GBR + R0, ult);",
1347 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1348 "R[n] = (((R[n] >> 16) & 0xffff)",
1349 " | ((R[m] << 16) & 0xffff0000));",
1352 /* start-sanitize-sh4 */
1353 #if 0
1354 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1355 "divl(0,R[n],R[m]);",
1357 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1358 "divl(0,R[n],R[m]);",
1360 #endif
1361 /* end-sanitize-sh4 */
1363 {0, 0}};
1365 /* Tables of things to put into enums for sh-opc.h */
1366 static char *nibble_type_list[] =
1368 "HEX_0",
1369 "HEX_1",
1370 "HEX_2",
1371 "HEX_3",
1372 "HEX_4",
1373 "HEX_5",
1374 "HEX_6",
1375 "HEX_7",
1376 "HEX_8",
1377 "HEX_9",
1378 "HEX_A",
1379 "HEX_B",
1380 "HEX_C",
1381 "HEX_D",
1382 "HEX_E",
1383 "HEX_F",
1384 "REG_N",
1385 "REG_M",
1386 "BRANCH_12",
1387 "BRANCH_8",
1388 "DISP_8",
1389 "DISP_4",
1390 "IMM_4",
1391 "IMM_4BY2",
1392 "IMM_4BY4",
1393 "PCRELIMM_8BY2",
1394 "PCRELIMM_8BY4",
1395 "IMM_8",
1396 "IMM_8BY2",
1397 "IMM_8BY4",
1400 static
1401 char *arg_type_list[] =
1403 "A_END",
1404 "A_BDISP12",
1405 "A_BDISP8",
1406 "A_DEC_M",
1407 "A_DEC_N",
1408 "A_DISP_GBR",
1409 "A_DISP_PC",
1410 "A_DISP_REG_M",
1411 "A_DISP_REG_N",
1412 "A_GBR",
1413 "A_IMM",
1414 "A_INC_M",
1415 "A_INC_N",
1416 "A_IND_M",
1417 "A_IND_N",
1418 "A_IND_R0_REG_M",
1419 "A_IND_R0_REG_N",
1420 "A_MACH",
1421 "A_MACL",
1422 "A_PR",
1423 "A_R0",
1424 "A_R0_GBR",
1425 "A_REG_M",
1426 "A_REG_N",
1427 "A_SR",
1428 "A_VBR",
1429 "A_SSR",
1430 "A_SPC",
1434 static void
1435 make_enum_list (name, s)
1436 char *name;
1437 char **s;
1439 int i = 1;
1440 printf ("typedef enum {\n");
1441 while (*s)
1443 printf ("\t%s,\n", *s);
1444 s++;
1445 i++;
1447 printf ("} %s;\n", name);
1450 static int
1451 qfunc (a, b)
1452 op *a;
1453 op *b;
1455 char bufa[9];
1456 char bufb[9];
1457 memcpy (bufa, a->code, 4);
1458 memcpy (bufa + 4, a->code + 12, 4);
1459 bufa[8] = 0;
1461 memcpy (bufb, b->code, 4);
1462 memcpy (bufb + 4, b->code + 12, 4);
1463 bufb[8] = 0;
1464 return (strcmp (bufa, bufb));
1467 static void
1468 sorttab ()
1470 op *p = tab;
1471 int len = 0;
1473 while (p->name)
1475 p++;
1476 len++;
1478 qsort (tab, len, sizeof (*p), qfunc);
1481 static void
1482 printonmatch (ptr, a, rep)
1483 char **ptr;
1484 char *a;
1485 char *rep;
1487 int l = strlen (a);
1488 if (strncmp (*ptr, a, l) == 0)
1490 printf ("%s", rep);
1491 *ptr += l;
1492 if (**ptr)
1493 printf (",");
1498 static
1499 void
1500 think (o)
1501 op *o;
1503 char *n;
1504 char *p;
1506 printf ("{\"");
1507 n = o->name;
1508 while (*n && *n != ' ')
1510 printf ("%c", *n);
1511 n++;
1513 printf ("\",{");
1515 p = n;
1517 if (!*p)
1519 printf ("0");
1521 while (*p)
1523 while (*p == ',' || *p == ' ')
1524 p++;
1525 printonmatch (&p, "#<imm>", "A_IMM");
1526 printonmatch (&p, "R0", "A_R0");
1527 printonmatch (&p, "<REG_N>", "A_REG_N");
1528 printonmatch (&p, "@<REG_N>+", "A_INC_N");
1529 printonmatch (&p, "@<REG_N>", "A_IND_N");
1530 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
1531 printonmatch (&p, "<REG_M>", " A_REG_M");
1532 printonmatch (&p, "@<REG_M>+", "A_INC_M");
1533 printonmatch (&p, "@<REG_M>", "A_IND_M");
1534 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
1535 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
1536 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1537 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1538 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1539 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1540 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
1541 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
1542 printonmatch (&p, "<bdisp8>", "A_BDISP8");
1543 printonmatch (&p, "<bdisp12>", "A_BDISP12");
1544 printonmatch (&p, "SR", "A_SR");
1545 printonmatch (&p, "GBR", "A_GBR");
1546 printonmatch (&p, "VBR", "A_VBR");
1547 printonmatch (&p, "SSR", "A_SSR");
1548 printonmatch (&p, "SPC", "A_SPC");
1549 printonmatch (&p, "MACH", "A_MACH");
1550 printonmatch (&p, "MACL", "A_MACL");
1551 printonmatch (&p, "PR", "A_PR");
1554 printf ("},{");
1556 p = o->code;
1557 while (*p)
1559 printonmatch (&p, "0000", "HEX_0");
1560 printonmatch (&p, "0001", "HEX_1");
1561 printonmatch (&p, "0010", "HEX_2");
1562 printonmatch (&p, "0011", "HEX_3");
1563 printonmatch (&p, "0100", "HEX_4");
1564 printonmatch (&p, "0101", "HEX_5");
1565 printonmatch (&p, "0110", "HEX_6");
1566 printonmatch (&p, "0111", "HEX_7");
1568 printonmatch (&p, "1000", "HEX_8");
1569 printonmatch (&p, "1001", "HEX_9");
1570 printonmatch (&p, "1010", "HEX_A");
1571 printonmatch (&p, "1011", "HEX_B");
1572 printonmatch (&p, "1100", "HEX_C");
1573 printonmatch (&p, "1101", "HEX_D");
1574 printonmatch (&p, "1110", "HEX_E");
1575 printonmatch (&p, "1111", "HEX_F");
1576 printonmatch (&p, "i8*1....", "IMM_8");
1577 printonmatch (&p, "i4*1", "IMM_4");
1578 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
1579 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
1580 printonmatch (&p, "i8*2....", "IMM_8BY2");
1581 printonmatch (&p, "i4*2", "IMM_4BY2");
1582 printonmatch (&p, "i8*4....", "IMM_8BY4");
1583 printonmatch (&p, "i4*4", "IMM_4BY4");
1584 printonmatch (&p, "i12.........", "BRANCH_12");
1585 printonmatch (&p, "i8p1....", "BRANCH_8");
1586 printonmatch (&p, "nnnn", "REG_N");
1587 printonmatch (&p, "mmmm", "REG_M");
1590 printf ("}},\n");
1593 static void
1594 gengastab ()
1596 op *p;
1597 sorttab ();
1598 for (p = tab; p->name; p++)
1600 printf ("%s %-30s\n", p->code, p->name);
1607 static void
1608 genopc ()
1610 op *p;
1611 make_enum_list ("sh_nibble_type", nibble_type_list);
1612 make_enum_list ("sh_arg_type", arg_type_list);
1614 printf ("typedef struct {\n");
1615 printf ("char *name;\n");
1616 printf ("sh_arg_type arg[3];\n");
1617 printf ("sh_nibble_type nibbles[4];\n");
1618 printf ("} sh_opcode_info;\n");
1619 printf ("#ifdef DEFINE_TABLE\n");
1620 printf ("sh_opcode_info sh_table[]={\n");
1621 for (p = tab; p->name; p++)
1623 printf ("\n/* %s %-20s*/", p->code, p->name);
1624 think (p);
1626 printf ("0};\n");
1627 printf ("#endif\n");
1635 /* Convert a string of 4 binary digits into an int */
1637 static
1639 bton (s)
1640 char *s;
1643 int n = 0;
1644 int v = 8;
1645 while (v)
1647 if (*s == '1')
1648 n |= v;
1649 v >>= 1;
1650 s++;
1652 return n;
1655 static unsigned char table[1 << 16];
1657 /* Take an opcode expand all varying fields in it out and fill all the
1658 right entries in 'table' with the opcode index*/
1660 static void
1661 expand_opcode (shift, val, i, s)
1662 int shift;
1663 int val;
1664 int i;
1665 char *s;
1667 int j;
1669 if (*s == 0)
1671 table[val] = i;
1673 else
1675 switch (s[0])
1678 case '0':
1679 case '1':
1682 int n = bton (s);
1683 if (n >= 0)
1685 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1687 break;
1689 case 'n':
1690 case 'm':
1691 for (j = 0; j < 16; j++)
1693 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1696 break;
1698 default:
1699 for (j = 0; j < (1 << (shift + 4)); j++)
1701 table[val | j] = i;
1707 /* Print the jump table used to index an opcode into a switch
1708 statement entry. */
1710 static void
1711 dumptable ()
1713 int lump = 256;
1714 int online = 16;
1716 int i = 0;
1718 while (i < 1 << 16)
1720 int j = 0;
1722 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1724 while (j < lump)
1726 int k = 0;
1727 while (k < online)
1729 printf ("%2d", table[i + j + k]);
1730 if (j + k < lump)
1731 printf (",");
1733 k++;
1735 j += k;
1736 printf ("\n");
1738 i += j;
1739 printf ("};\n");
1745 static void
1746 filltable ()
1748 op *p;
1749 int index = 1;
1751 sorttab ();
1752 for (p = tab; p->name; p++)
1754 p->index = index++;
1755 expand_opcode (12, 0, p->index, p->code);
1759 static void
1760 gensim ()
1762 op *p;
1763 int j;
1765 printf ("{\n");
1766 printf (" switch (jump_table[iword]) {\n");
1768 for (p = tab; p->name; p++)
1770 int sextbit = -1;
1771 int needm = 0;
1772 int needn = 0;
1774 char *s = p->code;
1776 printf (" /* %s %s */\n", p->name, p->code);
1777 printf (" case %d: \n", p->index);
1779 printf (" {\n");
1780 while (*s)
1782 switch (*s)
1784 case '0':
1785 case '1':
1786 case '.':
1787 s += 4;
1788 break;
1789 case 'n':
1790 printf (" int n = (iword >>8) & 0xf;\n");
1791 needn = 1;
1792 s += 4;
1793 break;
1794 case 'm':
1795 printf (" int m = (iword >>4) & 0xf;\n");
1796 needm = 1;
1797 s += 4;
1799 break;
1801 case 'i':
1802 printf (" int i = (iword & 0x");
1804 switch (s[1])
1806 case '4':
1807 printf ("f");
1808 break;
1809 case '8':
1810 printf ("ff");
1811 break;
1812 case '1':
1813 sextbit = 12;
1815 printf ("fff");
1816 break;
1818 printf (")");
1820 switch (s[3])
1822 case '1':
1823 break;
1824 case '2':
1825 printf ("<<1");
1826 break;
1827 case '4':
1828 printf ("<<2");
1829 break;
1831 printf (";\n");
1832 s += 4;
1835 if (sextbit > 0)
1837 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1838 sextbit - 1, sextbit - 1);
1841 if (needm && needn)
1842 printf (" TB(m,n);\n");
1843 else if (needm)
1844 printf (" TL(m);\n");
1845 else if (needn)
1846 printf (" TL(n);\n");
1849 /* Do the refs */
1850 char *r;
1851 for (r = p->refs; *r; r++)
1853 if (*r == '0') printf(" CREF(0);\n");
1854 if (*r == 'n') printf(" CREF(n);\n");
1855 if (*r == 'm') printf(" CREF(m);\n");
1859 printf (" {\n");
1860 for (j = 0; j < MAX_NR_STUFF; j++)
1862 if (p->stuff[j])
1864 printf (" %s\n", p->stuff[j]);
1867 printf (" }\n");
1870 /* Do the defs */
1871 char *r;
1872 for (r = p->defs; *r; r++)
1874 if (*r == '0') printf(" CDEF(0);\n");
1875 if (*r == 'n') printf(" CDEF(n);\n");
1876 if (*r == 'm') printf(" CDEF(m);\n");
1880 printf (" break;\n");
1881 printf (" }\n");
1883 printf (" default:\n");
1884 printf (" {\n");
1885 printf (" saved_state.asregs.exception = SIGILL;\n");
1886 printf (" }\n");
1887 printf (" }\n");
1888 printf ("}\n");
1892 static void
1893 gendefines ()
1895 op *p;
1896 filltable();
1897 for (p = tab; p->name; p++)
1899 char *s = p->name;
1900 printf ("#define OPC_");
1901 while (*s) {
1902 if (isupper(*s))
1903 *s = tolower(*s);
1904 if (isalpha(*s)) printf("%c", *s);
1905 if (*s == ' ') printf("_");
1906 if (*s == '@') printf("ind_");
1907 if (*s == ',') printf("_");
1908 s++;
1910 printf(" %d\n",p->index);
1915 main (ac, av)
1916 int ac;
1917 char **av;
1919 /* verify the table before anything else */
1921 op *p;
1922 for (p = tab; p->name; p++)
1924 /* check that the code field contains 16 bits */
1925 if (strlen (p->code) != 16)
1927 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1928 p->code, strlen (p->code), p->name);
1929 abort ();
1934 /* now generate the requested data */
1935 if (ac > 1)
1937 if (strcmp (av[1], "-t") == 0)
1939 gengastab ();
1941 else if (strcmp (av[1], "-d") == 0)
1943 gendefines ();
1945 else if (strcmp (av[1], "-s") == 0)
1947 filltable ();
1948 dumptable ();
1951 else if (strcmp (av[1], "-x") == 0)
1953 filltable ();
1954 gensim ();
1957 else
1959 genopc ();
1961 return 0;