]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/sh/gencode.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / sim / sh / gencode.c
CommitLineData
594266fc
SC
1/* Simulator/Opcode generator for the Hitachi Super-H architecture.
2
3 Written by Steve Chamberlain of Cygnus Support.
4 sac@cygnus.com
5
6 This file is part of SH sim
7
8
9 THIS SOFTWARE IS NOT COPYRIGHTED
10
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.
14
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.
18
19*/
20
21/* This program generates the opcode table for the assembler and
22 the simulator code
23
24 -t prints a pretty table for the assembler manual
25 -s generates the simulator code jump table
acae2683 26 -d generates a define table
594266fc
SC
27 -x generates the simulator code switch statement
28 default generates the opcode tables
29
30*/
31
acae2683
TG
32#include <stdio.h>
33
4de6b5d3
AC
34#define MAX_NR_STUFF 20
35
594266fc
SC
36typedef struct
37{
4de6b5d3
AC
38 char *defs;
39 char *refs;
594266fc
SC
40 char *name;
41 char *code;
4de6b5d3 42 char *stuff[MAX_NR_STUFF];
594266fc
SC
43 int index;
44}
45
46op;
47
48
49op tab[] =
50{
51
4de6b5d3
AC
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 "}",
58 },
59 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
60 "R[n] += R[m];",
61 },
62
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));",
68 },
69
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;",
74 },
75
76 { "0", "", "and #<imm>,R0", "11001001i8*1....",
77 "R0 &= i;",
78 },
79 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
80 "R[n] &= R[m];",
81 },
82 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
83 "MA (1);",
84 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
85 },
86
87 { "", "", "bf <bdisp8>", "10001011i8p1....",
88 "if (!T) {",
89 " nia = PC + 4 + (SEXT(i) * 2);",
90 " cycles += 2;",
91 "}",
92 },
93
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95 "if (!T) {",
96 " nia = PC + 4 + (SEXT (i) * 2);",
97 " cycles += 2;",
98 " Delay_Slot (PC + 2);",
99 "}",
100 },
101
102 { "", "", "bra <bdisp12>", "1010i12.........",
103 "nia = PC + 4 + (SEXT12 (i) * 2);",
104 "Delay_Slot (PC + 2);",
105 },
106
107 { "", "n", "braf <REG_N>", "0000nnnn00100011",
108 "nia = PC + 4 + R[n];",
109 "Delay_Slot (PC + 2);",
110 },
111
112 { "", "", "bsr <bdisp12>", "1011i12.........",
113 "PR = PC + 4;",
114 "nia = PC + 4 + (SEXT12 (i) * 2);",
115 "Delay_Slot (PC + 2);",
116 },
117
118 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
119 "PR = PC + 4;",
120 "nia = PC + 4 + R[n];",
121 "Delay_Slot (PC + 2);",
122 },
123
124 { "", "", "bt <bdisp8>", "10001001i8p1....",
125 "if (T) {",
126 " nia = PC + 4 + (SEXT (i) * 2);",
127 " cycles += 2;",
128 "}",
129 },
130
131 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
132 "if (T) {",
133 " nia = PC + 4 + (SEXT (i) * 2);",
134 " cycles += 2;",
135 " Delay_Slot (PC + 2);",
136 "}",
137 },
138
139 { "", "", "clrmac", "0000000000101000",
140 "MACH = 0;",
141 "MACL = 0;",
142 },
143
144 { "", "", "clrs", "0000000001001000",
145 "SET_SR_S (0);",
146 },
147
148 { "", "", "clrt", "0000000000001000",
149 "SET_SR_T (0);",
150 },
151
152 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
153 "SET_SR_T (R0 == SEXT (i));",
154 },
155 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
156 "SET_SR_T (R[n] == R[m]);",
157 },
158 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
159 "SET_SR_T (R[n] >= R[m]);",
160 },
161 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
162 "SET_SR_T (R[n] > R[m]);",
163 },
164 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
165 "SET_SR_T (UR[n] > UR[m]);",
166 },
167 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
168 "SET_SR_T (UR[n] >= UR[m]);",
169 },
170 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
171 "SET_SR_T (R[n] > 0);",
172 },
173 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
174 "SET_SR_T (R[n] >= 0);",
175 },
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));",
182 },
183
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);",
188 },
189
190 { "", "", "div0u", "0000000000011001",
191 "SET_SR_M (0);",
192 "SET_SR_Q (0);",
193 "SET_SR_T (0);",
194 },
195
196 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
197 "div1 (R, m, n/*, T*/);",
198 },
199
200 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
201 "dmul (1/*signed*/, R[n], R[m]);",
202 },
203
204 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
205 "dmul (0/*unsigned*/, R[n], R[m]);",
206 },
207
208 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
209 "R[n]--;",
210 "SET_SR_T (R[n] == 0);",
211 },
212
213 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
214 "R[n] = SEXT (R[m]);",
215 },
216 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
217 "R[n] = SEXTW (R[m]);",
218 },
219
220 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
221 "R[n] = (R[m] & 0xff);",
222 },
223 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
224 "R[n] = (R[m] & 0xffff);",
225 },
226
227 /* sh3e */
228 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
229 "FP_UNARY (n, fabs);",
230 "/* FIXME: FR(n) &= 0x7fffffff; */",
231 },
232
233 /* sh3e */
234 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
235 "FP_OP (n, +, m);",
236 },
237
238 /* sh3e */
239 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
240 "FP_CMP (n, ==, m);",
241 },
242 /* sh3e */
243 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
244 "FP_CMP (n, >, m);",
245 },
246
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 "}",
257 },
258 /* end-sanitize-sh4 */
259
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 "}",
270 },
271 /* end-sanitize-sh4 */
272
273 /* sh3e */
274 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
275 "FP_OP (n, /, m);",
276 "/* FIXME: check for DP and (n & 1) == 0? */",
277 },
278
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? */",
284 },
285 /* end-sanitize-sh4 */
286
287 /* sh3e */
288 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
289 "SET_FR (n, (float)0.0);",
290 "/* FIXME: check for DP and (n & 1) == 0? */",
291 },
292
293 /* sh3e */
294 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
295 "SET_FR (n, (float)1.0);",
296 "/* FIXME: check for DP and (n & 1) == 0? */",
297 },
298
299 /* sh3e */
300 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
301 "char buf[4];",
302 "*(float *)buf = FR(n);",
303 "FPUL = *(int *)buf;",
304 },
305
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 "}",
316 },
317
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? */",
322 },
323
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 "}",
338 },
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 "}",
352 },
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 "}",
366 },
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 "}",
382 },
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 "}",
398 },
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 "}",
412 },
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 "}",
426 },
427
428 /* start-sanitize-sh4 */
429 /* See fmov instructions above for move to/from extended fp
430 registers */
431 /* end-sanitize-sh4 */
432
433 /* sh3e */
434 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
435 "FP_OP(n, *, m);",
436 },
437
438 /* sh3e */
439 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
440 "FP_UNARY(n, -);",
441 },
442
443 /* start-sanitize-sh4 */
444 { "", "", "frchg", "1111101111111101",
445 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
446 },
447 /* end-sanitize-sh4 */
448
449 /* start-sanitize-sh4 */
450 { "", "", "fschg", "1111001111111101",
451 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
452 },
453 /* end-sanitize-sh4 */
454
455 /* sh3e */
456 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
457 "FP_UNARY(n, sqrt);",
458 },
459
460 /* sh3e */
461 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
462 "FP_OP(n, -, m);",
463 },
464
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);",
480 },
481
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)));",
489 },
490 /* start-sanitize-sh4 */
491#endif
492 /* end-sanitize-sh4 */
493
494 /* sh3e */
495 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
496 "char buf[4];",
497 "*(int *)buf = FPUL;",
498 "SET_FR (n, *(float *)buf);",
499 },
500
501 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
502 "nia = R[n];",
503 "Delay_Slot (PC + 2);",
504 },
505
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);",
512 },
513
514 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
515 "GBR = R[n];",
516 "/* FIXME: user mode */",
517 },
518 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
519 "SET_SR (R[n]);",
520 "/* FIXME: user mode */",
521 },
522 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
523 "VBR = R[n];",
524 "/* FIXME: user mode */",
525 },
526 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
527 "SSR = R[n];",
528 "/* FIXME: user mode */",
529 },
530 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
531 "SPC = R[n];",
532 "/* FIXME: user mode */",
533 },
534 /* start-sanitize-sh4 */
535#if 0
536 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
537 "DBR = R[n];",
538 "/* FIXME: user mode */",
539 },
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 */",
545 },
546 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
547 "SET_Rn_BANK (1, R[n]);",
548 "/* FIXME: user mode */",
549 },
550 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
551 "SET_Rn_BANK (2, R[n]);",
552 "/* FIXME: user mode */",
553 },
554 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
555 "SET_Rn_BANK (3, R[n]);",
556 "/* FIXME: user mode */",
557 },
558 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
559 "SET_Rn_BANK (4, R[n]);",
560 "/* FIXME: user mode */",
561 },
562 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
563 "SET_Rn_BANK (5, R[n]);",
564 "/* FIXME: user mode */",
565 },
566 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
567 "SET_Rn_BANK (6, R[n]);",
568 "/* FIXME: user mode */",
569 },
570 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
571 "SET_Rn_BANK (7, R[n]);",
572 "/* FIXME: user mode */",
573 },
574 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
575 "MA (1);",
576 "GBR = RLAT (R[n]);",
577 "R[n] += 4;",
578 "/* FIXME: user mode */",
579 },
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 */",
585 },
586 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
587 "MA (1);",
588 "VBR = RLAT (R[n]);",
589 "R[n] += 4;",
590 "/* FIXME: user mode */",
591 },
592 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
593 "MA (1);",
594 "SSR = RLAT (R[n]);",
595 "R[n] += 4;",
596 "/* FIXME: user mode */",
597 },
598 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
599 "MA (1);",
600 "SPC = RLAT (R[n]);",
601 "R[n] += 4;",
602 "/* FIXME: user mode */",
603 },
604 /* start-sanitize-sh4 */
594266fc 605#if 0
4de6b5d3
AC
606 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
607 "MA (1);",
608 "DBR = RLAT (R[n]);",
609 "R[n] += 4;",
610 "/* FIXME: user mode */",
611 },
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 */",
619 },
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 */",
625 },
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 */",
631 },
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 */",
637 },
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 */",
643 },
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 */",
649 },
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 */",
655 },
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 */",
661 },
662
663 /* sh3e */
664 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
665 "FPUL = R[n];",
666 },
667 /* sh3e */
668 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
669 "MA (1);",
670 "FPUL = RLAT(R[n]);",
671 "R[n] += 4;",
672 },
673 /* sh3e */
674 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
675 "SET_FPSCR(R[n]);",
676 },
677 /* sh3e */
678 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
679 "MA (1);",
680 "SET_FPSCR (RLAT(R[n]));",
681 "R[n] += 4;",
682 },
683
684 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
685 "MACH = R[n];",
686 },
687 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
688 "MACL= R[n];",
689 },
690 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
691 "PR = R[n];",
692 },
693 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
694 "MA (1);",
695 "MACH = SEXT(RLAT(R[n]));",
696 "R[n]+=4;",
697 },
698 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
699 "MA (1);",
700 "MACL = RLAT(R[n]);",
701 "R[n]+=4;",
702 },
703 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
704 "MA (1);",
705 "PR = RLAT(R[n]);",
706 "R[n]+=4;;",
707 },
708
709 { "", "", "ldtlb", "0000000000111000",
710 "/* FIXME: XXX*/ abort();",
711 },
712
713 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
714 "trap (255,R0,memory,maskl,maskw,little_endian);",
715 "/* FIXME: mac.l support */",
716 },
717
718 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
719 "macw(R0,memory,n,m);",
720 },
721
722 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
723 "R[n] = SEXT(i);",
724 },
725 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
726 "R[n] = R[m];",
727 },
728
729 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
730 "MA (1);",
731 "R0 = RSBAT (i + GBR);",
732 "L (0);",
733 },
734 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
735 "MA (1);",
736 "R0 = RSBAT (i + R[m]);",
737 "L (0);",
738 },
739 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
740 "MA (1);",
741 "R[n] = RSBAT (R0 + R[m]);",
742 "L (n);",
743 },
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);",
749 },
750 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
751 "MA (1);",
752 "WBAT (R[n], R[m]);",
753 },
754 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
755 "MA (1);",
756 "WBAT (i + GBR, R0);",
757 },
758 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
759 "MA (1);",
760 "WBAT (i + R[m], R0);",
761 },
762 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
763 "MA (1);",
764 "WBAT (R[n] + R0, R[m]);",
765 },
766 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
767 "MA (1);",
768 "R[n] -= 1;",
769 "WBAT (R[n], R[m]);",
770 },
771 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
772 "MA (1);",
773 "R[n] = RSBAT (R[m]);",
774 "L (n);",
775 },
776
777 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
778 "MA (1);",
779 "R0 = RLAT (i + GBR);",
780 "L (0);",
781 },
782 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
783 "MA (1);",
784 "R[n] = RLAT((PC & ~3) + 4 + i);",
785 "L (n);",
786 },
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);",
791 },
792 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
793 "MA (1);",
794 "R[n] = RLAT (R0 + R[m]);",
795 "L (n);",
796 },
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);",
802 },
803 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
804 "MA (1);",
805 "R[n] = RLAT (R[m]);",
806 "L (n);",
807 },
808 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
809 "MA (1);",
810 "WLAT (i + GBR, R0);",
811 },
812 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
813 "MA (1);",
814 "WLAT (i + R[n], R[m]);",
815 },
816 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
817 "MA (1);",
818 "WLAT (R0 + R[n], R[m]);",
819 },
820 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
821 "MA (1) ;",
822 "R[n] -= 4;",
823 "WLAT (R[n], R[m]);",
824 },
825 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
826 "MA (1);",
827 "WLAT (R[n], R[m]);",
828 },
829
830 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
831 "MA (1)",
832 ";R0 = RSWAT (i + GBR);",
833 "L (0);",
834 },
835 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
836 "MA (1);",
837 "R[n] = RSWAT (PC + 4 + i);",
838 "L (n);",
839 },
840 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
841 "MA (1);",
842 "R0 = RSWAT (i + R[m]);",
843 "L (0);",
844 },
845 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
846 "MA (1);",
847 "R[n] = RSWAT (R0 + R[m]);",
848 "L (n);",
849 },
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);",
855 },
856 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
857 "MA (1);",
858 "R[n] = RSWAT (R[m]);",
859 "L (n);",
860 },
861 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
862 "MA (1);",
863 "WWAT (i + GBR, R0);",
864 },
865 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
866 "MA (1);",
867 "WWAT (i + R[m], R0);",
868 },
869 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
870 "MA (1);",
871 "WWAT (R0 + R[n], R[m]);",
872 },
873 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
874 "MA (1);",
875 "R[n] -= 2;",
876 "WWAT (R[n], R[m]);",
877 },
878 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
879 "MA (1);",
880 "WWAT (R[n], R[m]);",
881 },
882
883 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
884 "R0 = ((i + 4 + PC) & ~0x3);",
885 },
886
887 /* start-sanitize-sh4 */
888 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
889 "/* FIXME: Not implemented */",
890 "saved_state.asregs.exception = SIGILL;",
891 },
892 /* end-sanitize-sh4 */
893
894 { "n", "", "movt <REG_N>", "0000nnnn00101001",
895 "R[n] = T;",
896 },
897
898 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
899 "MACL = ((int)R[n]) * ((int)R[m]);",
900 },
901#if 0
902 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
903 "MACL = R[n] * R[m];",
904 },
594266fc
SC
905#endif
906
4de6b5d3
AC
907 /* muls.w - see muls */
908 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
909 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
910 },
911
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]));",
916 },
917
918 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
919 "R[n] = - R[m];",
920 },
921
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));",
927 },
928
929 { "", "", "nop", "0000000000001001",
930 "/* nop */",
931 },
932
933 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
934 "R[n] = ~R[m];",
935 },
936
937 /* start-sanitize-sh4 */
938 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
939 "/* FIXME: Not implemented */",
940 "saved_state.asregs.exception = SIGILL;",
941 },
942 /* end-sanitize-sh4 */
943
944 /* start-sanitize-sh4 */
945 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
946 "/* FIXME: Not implemented */",
947 "saved_state.asregs.exception = SIGILL;",
948 },
949 /* end-sanitize-sh4 */
950
951 /* start-sanitize-sh4 */
952 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
953 "RSBAT (R[n]); /* Take exceptions like byte load. */",
954 "/* FIXME: Cache not implemented */",
955 },
956 /* end-sanitize-sh4 */
957
958 { "0", "", "or #<imm>,R0", "11001011i8*1....",
959 "R0 |= i;",
960 },
961 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
962 "R[n] |= R[m];",
963 },
964 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
965 "MA (1);",
966 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
967 },
968
969 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
970 "/* Except for the effect on the cache - which is not simulated -",
971 " this is like a nop. */",
972 },
973
974 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
975 "ult = R[n] < 0;",
976 "R[n] = (R[n] << 1) | T;",
977 "SET_SR_T (ult);",
978 },
979
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);",
984 },
985
986 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
987 "SET_SR_T (R[n] < 0);",
988 "R[n] <<= 1;",
989 "R[n] |= T;",
990 },
991
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);",
996 },
997
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
1012 },
1013
1014 { "", "", "rts", "0000000000001011",
1015 "nia = PR;",
1016 "Delay_Slot (PC + 2);",
1017 },
1018
1019 { "", "", "sets", "0000000001011000",
1020 "SET_SR_S (1);",
1021 },
1022
1023 { "", "", "sett", "0000000000011000",
1024 "SET_SR_T (1);",
1025 },
1026
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));",
1029 },
1030
1031 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1032 "SET_SR_T (R[n] < 0);",
1033 "R[n] <<= 1;",
1034 },
1035
1036 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1037 "SET_SR_T (R[n] & 1);",
1038 "R[n] = R[n] >> 1;",
1039 },
1040
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));",
1043 },
1044
1045 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1046 "SET_SR_T (R[n] < 0);",
1047 "R[n] <<= 1;",
1048 },
1049
1050 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1051 "R[n] <<= 2;",
1052 },
1053 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1054 "R[n] <<= 8;",
1055 },
1056 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1057 "R[n] <<= 16;",
1058 },
1059
1060 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1061 "SET_SR_T (R[n] & 1);",
1062 "R[n] = UR[n] >> 1;",
1063 },
1064
1065 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1066 "R[n] = UR[n] >> 2;",
1067 },
1068 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1069 "R[n] = UR[n] >> 8;",
1070 },
1071 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1072 "R[n] = UR[n] >> 16;",
1073 },
1074
1075 { "", "", "sleep", "0000000000011011",
1076 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
1077 "nia = PC;",
1078 },
1079
1080 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
1081 "R[n] = GBR;",
1082 },
1083 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
1084 "R[n] = GET_SR ();",
1085 },
1086 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
1087 "R[n] = VBR;",
1088 },
1089 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
1090 "R[n] = SSR;",
1091 },
1092 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
1093 "R[n] = SPC;",
1094 },
1095 /* start-sanitize-sh4 */
1096#if 0
1097 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1098 "R[n] = SGR;",
1099 },
1100 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1101 "R[n] = DBR;",
1102 },
1103#endif
1104 /* end-sanitize-sh4 */
1105 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
1106 "R[n] = Rn_BANK (0);",
1107 },
1108 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
1109 "R[n] = Rn_BANK (1);",
1110 },
1111 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
1112 "R[n] = Rn_BANK (2);",
1113 },
1114 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
1115 "R[n] = Rn_BANK (3);",
1116 },
1117 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
1118 "R[n] = Rn_BANK (4);",
1119 },
1120 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
1121 "R[n] = Rn_BANK (5);",
1122 },
1123 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
1124 "R[n] = Rn_BANK (6);",
1125 },
1126 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
1127 "R[n] = Rn_BANK (7);",
1128 },
1129 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
1130 "MA (1);",
1131 "R[n] -= 4;",
1132 "WLAT (R[n], GBR);;",
1133 },
1134 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
1135 "MA (1);",
1136 "R[n] -= 4;",
1137 "WLAT (R[n], GET_SR());",
1138 },
1139 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
1140 "MA (1);",
1141 "R[n] -= 4;",
1142 "WLAT (R[n], VBR);",
1143 },
1144 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
1145 "MA (1);",
1146 "R[n] -= 4;",
1147 "WLAT (R[n], SSR);",
1148 },
1149 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
1150 "MA (1);",
1151 "R[n] -= 4;",
1152 "WLAT (R[n], SPC);",
1153 },
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);",
1160 },
1161 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1162 "MA (1);",
1163 "R[n] -= 4;",
1164 "WLAT (R[n], DBR);",
1165 },
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));",
1172 },
1173 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
1174 "MA (1);",
1175 "R[n] -= 4;",
1176 "WLAT (R[n], Rn_BANK (1));",
1177 },
1178 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
1179 "MA (1);",
1180 "R[n] -= 4;",
1181 "WLAT (R[n], Rn_BANK (2));",
1182 },
1183 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
1184 "MA (1);",
1185 "R[n] -= 4;",
1186 "WLAT (R[n], Rn_BANK (3));",
1187 },
1188 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
1189 "MA (1);",
1190 "R[n] -= 4;",
1191 "WLAT (R[n], Rn_BANK (4));",
1192 },
1193 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
1194 "MA (1);",
1195 "R[n] -= 4;",
1196 "WLAT (R[n], Rn_BANK (5));",
1197 },
1198 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1199 "MA (1);",
1200 "R[n] -= 4;",
1201 "WLAT (R[n], Rn_BANK (6));",
1202 },
1203 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1204 "MA (1);",
1205 "R[n] -= 4;",
1206 "WLAT (R[n], Rn_BANK (7));",
1207 },
1208
1209 /* sh3e */
1210 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1211 "R[n] = FPUL;",
1212 },
1213 /* sh3e */
1214 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1215 "MA (1);",
1216 "R[n] -= 4;",
1217 "WLAT (R[n], FPUL);",
1218 },
1219 /* sh3e */
1220 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1221 "R[n] = GET_FPSCR ();",
1222 },
1223 /* sh3e */
1224 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1225 "MA (1);",
1226 "R[n] -= 4;",
1227 "WLAT (R[n], GET_FPSCR ());",
1228 },
1229
1230 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1231 "R[n] = MACH;",
1232 },
1233 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1234 "R[n] = MACL;",
1235 },
1236 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1237 "R[n] = PR;",
1238 },
1239 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1240 "MA (1);",
1241 "R[n] -= 4;",
1242 "WLAT (R[n], MACH);",
1243 },
1244 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1245 "MA (1);",
1246 "R[n] -= 4;",
1247 "WLAT (R[n], MACL);",
1248 },
1249 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1250 "MA (1);",
1251 "R[n] -= 4;",
1252 "WLAT (R[n], PR);",
1253 },
1254
1255 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1256 "R[n] -= R[m];",
1257 },
1258
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));",
1264 },
1265
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;",
1270 },
1271
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));",
1276 },
1277 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1278 "R[n] = (((R[m] << 16) & 0xffff0000)",
1279 " | ((R[m] >> 16) & 0x00ffff));",
1280 },
1281
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);",
1287 },
1288
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
1321 },
1322
1323 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1324 "SET_SR_T ((R[n] & R[m]) == 0);",
1325 },
1326 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1327 "SET_SR_T ((R0 & i) == 0);",
1328 },
1329 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1330 "MA (1);",
1331 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1332 },
1333
1334 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1335 "R0 ^= i;",
1336 },
1337 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1338 "R[n] ^= R[m];",
1339 },
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);",
1345 },
1346
1347 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1348 "R[n] = (((R[n] >> 16) & 0xffff)",
1349 " | ((R[m] << 16) & 0xffff0000));",
1350 },
1351
1352 /* start-sanitize-sh4 */
1353#if 0
1354 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1355 "divl(0,R[n],R[m]);",
1356 },
1357 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1358 "divl(0,R[n],R[m]);",
1359 },
1360#endif
1361 /* end-sanitize-sh4 */
9999417e 1362
594266fc
SC
1363 {0, 0}};
1364
1365/* Tables of things to put into enums for sh-opc.h */
1366static char *nibble_type_list[] =
1367{
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",
1398 0
1399};
1400static
1401char *arg_type_list[] =
1402{
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",
2434e384
C
1429 "A_SSR",
1430 "A_SPC",
594266fc
SC
1431 0,
1432};
1433
1434static void
1435make_enum_list (name, s)
1436 char *name;
1437 char **s;
1438{
1439 int i = 1;
1440 printf ("typedef enum {\n");
1441 while (*s)
1442 {
acae2683 1443 printf ("\t%s,\n", *s);
594266fc
SC
1444 s++;
1445 i++;
1446 }
1447 printf ("} %s;\n", name);
1448}
1449
acae2683
TG
1450static int
1451qfunc (a, b)
1452 op *a;
1453 op *b;
594266fc 1454{
acae2683
TG
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;
594266fc 1460
acae2683
TG
1461 memcpy (bufb, b->code, 4);
1462 memcpy (bufb + 4, b->code + 12, 4);
1463 bufb[8] = 0;
1464 return (strcmp (bufa, bufb));
594266fc
SC
1465}
1466
acae2683
TG
1467static void
1468sorttab ()
594266fc 1469{
acae2683
TG
1470 op *p = tab;
1471 int len = 0;
594266fc 1472
acae2683 1473 while (p->name)
594266fc 1474 {
acae2683
TG
1475 p++;
1476 len++;
594266fc 1477 }
acae2683 1478 qsort (tab, len, sizeof (*p), qfunc);
594266fc
SC
1479}
1480
acae2683
TG
1481static void
1482printonmatch (ptr, a, rep)
594266fc
SC
1483 char **ptr;
1484 char *a;
1485 char *rep;
1486{
1487 int l = strlen (a);
1488 if (strncmp (*ptr, a, l) == 0)
1489 {
1490 printf ("%s", rep);
1491 *ptr += l;
1492 if (**ptr)
1493 printf (",");
1494 }
1495}
1496
acae2683
TG
1497
1498static
1499void
594266fc
SC
1500think (o)
1501 op *o;
1502{
594266fc
SC
1503 char *n;
1504 char *p;
1505
1506 printf ("{\"");
1507 n = o->name;
1508 while (*n && *n != ' ')
1509 {
1510 printf ("%c", *n);
1511 n++;
1512 }
1513 printf ("\",{");
1514
1515 p = n;
1516
1517 if (!*p)
1518 {
1519 printf ("0");
1520 }
1521 while (*p)
1522 {
1523 while (*p == ',' || *p == ' ')
1524 p++;
acae2683
TG
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");
2434e384
C
1547 printonmatch (&p, "SSR", "A_SSR");
1548 printonmatch (&p, "SPC", "A_SPC");
acae2683
TG
1549 printonmatch (&p, "MACH", "A_MACH");
1550 printonmatch (&p, "MACL", "A_MACL");
1551 printonmatch (&p, "PR", "A_PR");
594266fc
SC
1552
1553 }
1554 printf ("},{");
1555
1556 p = o->code;
1557 while (*p)
1558 {
acae2683
TG
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");
1567
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");
594266fc
SC
1588
1589 }
1590 printf ("}},\n");
1591}
1592
acae2683
TG
1593static void
1594gengastab ()
594266fc 1595{
acae2683
TG
1596 op *p;
1597 sorttab ();
1598 for (p = tab; p->name; p++)
1599 {
1600 printf ("%s %-30s\n", p->code, p->name);
1601 }
1602
594266fc 1603
594266fc
SC
1604}
1605
1606
acae2683
TG
1607static void
1608genopc ()
594266fc 1609{
acae2683
TG
1610 op *p;
1611 make_enum_list ("sh_nibble_type", nibble_type_list);
1612 make_enum_list ("sh_arg_type", arg_type_list);
594266fc 1613
acae2683
TG
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++)
594266fc 1622 {
2ca7c3c4 1623 printf ("\n/* %s %-20s*/", p->code, p->name);
acae2683 1624 think (p);
594266fc 1625 }
acae2683
TG
1626 printf ("0};\n");
1627 printf ("#endif\n");
1628}
1629
1630
1631
594266fc 1632
594266fc 1633
594266fc
SC
1634
1635/* Convert a string of 4 binary digits into an int */
1636
1637static
1638int
1639bton (s)
1640 char *s;
1641
1642{
1643 int n = 0;
1644 int v = 8;
1645 while (v)
1646 {
1647 if (*s == '1')
1648 n |= v;
1649 v >>= 1;
1650 s++;
1651 }
1652 return n;
1653}
1654
acae2683 1655static unsigned char table[1 << 16];
594266fc 1656
acae2683 1657/* Take an opcode expand all varying fields in it out and fill all the
594266fc 1658 right entries in 'table' with the opcode index*/
acae2683
TG
1659
1660static void
594266fc 1661expand_opcode (shift, val, i, s)
acae2683
TG
1662 int shift;
1663 int val;
1664 int i;
594266fc
SC
1665 char *s;
1666{
1667 int j;
1668
1669 if (*s == 0)
1670 {
1671 table[val] = i;
1672 }
1673 else
1674 {
1675 switch (s[0])
1676 {
1677
1678 case '0':
1679 case '1':
1680 {
1681
1682 int n = bton (s);
1683 if (n >= 0)
1684 {
1685 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1686 }
1687 break;
1688 }
1689 case 'n':
1690 case 'm':
1691 for (j = 0; j < 16; j++)
1692 {
1693 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1694
1695 }
1696 break;
1697
1698 default:
1699 for (j = 0; j < (1 << (shift + 4)); j++)
1700 {
1701 table[val | j] = i;
1702 }
1703 }
1704 }
1705}
1706
1707/* Print the jump table used to index an opcode into a switch
acae2683 1708 statement entry. */
594266fc 1709
acae2683 1710static void
594266fc
SC
1711dumptable ()
1712{
1713 int lump = 256;
1714 int online = 16;
1715
1716 int i = 0;
1717
1718 while (i < 1 << 16)
1719 {
1720 int j = 0;
594266fc
SC
1721
1722 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1723
1724 while (j < lump)
1725 {
1726 int k = 0;
1727 while (k < online)
1728 {
1729 printf ("%2d", table[i + j + k]);
1730 if (j + k < lump)
1731 printf (",");
1732
1733 k++;
1734 }
1735 j += k;
1736 printf ("\n");
1737 }
1738 i += j;
1739 printf ("};\n");
1740 }
1741
1742}
1743
1744
1745static void
1746filltable ()
1747{
1748 op *p;
1749 int index = 1;
1750
1751 sorttab ();
1752 for (p = tab; p->name; p++)
1753 {
1754 p->index = index++;
1755 expand_opcode (12, 0, p->index, p->code);
1756 }
1757}
1758
acae2683 1759static void
594266fc
SC
1760gensim ()
1761{
1762 op *p;
1763 int j;
1764
1765 printf ("{\n");
4de6b5d3 1766 printf (" switch (jump_table[iword]) {\n");
594266fc
SC
1767
1768 for (p = tab; p->name; p++)
1769 {
1770 int sextbit = -1;
acae2683
TG
1771 int needm = 0;
1772 int needn = 0;
1773
594266fc
SC
1774 char *s = p->code;
1775
4de6b5d3
AC
1776 printf (" /* %s %s */\n", p->name, p->code);
1777 printf (" case %d: \n", p->index);
594266fc 1778
4de6b5d3 1779 printf (" {\n");
594266fc
SC
1780 while (*s)
1781 {
1782 switch (*s)
1783 {
1784 case '0':
1785 case '1':
1786 case '.':
1787 s += 4;
1788 break;
1789 case 'n':
4de6b5d3 1790 printf (" int n = (iword >>8) & 0xf;\n");
acae2683 1791 needn = 1;
594266fc
SC
1792 s += 4;
1793 break;
1794 case 'm':
4de6b5d3 1795 printf (" int m = (iword >>4) & 0xf;\n");
acae2683 1796 needm = 1;
594266fc
SC
1797 s += 4;
1798
1799 break;
1800
1801 case 'i':
4de6b5d3 1802 printf (" int i = (iword & 0x");
594266fc
SC
1803
1804 switch (s[1])
1805 {
1806 case '4':
1807 printf ("f");
1808 break;
1809 case '8':
1810 printf ("ff");
1811 break;
1812 case '1':
1813 sextbit = 12;
acae2683 1814
594266fc
SC
1815 printf ("fff");
1816 break;
1817 }
1818 printf (")");
1819
1820 switch (s[3])
1821 {
1822 case '1':
1823 break;
1824 case '2':
1825 printf ("<<1");
1826 break;
1827 case '4':
1828 printf ("<<2");
1829 break;
1830 }
1831 printf (";\n");
1832 s += 4;
1833 }
1834 }
acae2683 1835 if (sextbit > 0)
594266fc 1836 {
4de6b5d3
AC
1837 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1838 sextbit - 1, sextbit - 1);
594266fc 1839 }
4de6b5d3 1840
acae2683 1841 if (needm && needn)
4de6b5d3 1842 printf (" TB(m,n);\n");
acae2683 1843 else if (needm)
4de6b5d3 1844 printf (" TL(m);\n");
acae2683 1845 else if (needn)
4de6b5d3
AC
1846 printf (" TL(n);\n");
1847
1848 {
1849 /* Do the refs */
1850 char *r;
1851 for (r = p->refs; *r; r++)
1852 {
1853 if (*r == '0') printf(" CREF(0);\n");
1854 if (*r == 'n') printf(" CREF(n);\n");
1855 if (*r == 'm') printf(" CREF(m);\n");
1856 }
1857 }
1858
1859 printf (" {\n");
1860 for (j = 0; j < MAX_NR_STUFF; j++)
594266fc
SC
1861 {
1862 if (p->stuff[j])
1863 {
4de6b5d3 1864 printf (" %s\n", p->stuff[j]);
594266fc
SC
1865 }
1866 }
4de6b5d3 1867 printf (" }\n");
acae2683 1868
acae2683 1869 {
4de6b5d3 1870 /* Do the defs */
acae2683 1871 char *r;
acae2683
TG
1872 for (r = p->defs; *r; r++)
1873 {
4de6b5d3
AC
1874 if (*r == '0') printf(" CDEF(0);\n");
1875 if (*r == 'n') printf(" CDEF(n);\n");
1876 if (*r == 'm') printf(" CDEF(m);\n");
1877 }
acae2683 1878 }
4de6b5d3
AC
1879
1880 printf (" break;\n");
1881 printf (" }\n");
594266fc 1882 }
4de6b5d3
AC
1883 printf (" default:\n");
1884 printf (" {\n");
1885 printf (" saved_state.asregs.exception = SIGILL;\n");
1886 printf (" }\n");
1887 printf (" }\n");
1888 printf ("}\n");
594266fc
SC
1889}
1890
1891
acae2683
TG
1892static void
1893gendefines ()
1894{
1895 op *p;
1896 filltable();
1897 for (p = tab; p->name; p++)
1898 {
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++;
1909 }
1910 printf(" %d\n",p->index);
1911 }
1912}
1913
594266fc
SC
1914int
1915main (ac, av)
acae2683 1916 int ac;
594266fc 1917 char **av;
594266fc 1918{
4de6b5d3
AC
1919 /* verify the table before anything else */
1920 {
1921 op *p;
1922 for (p = tab; p->name; p++)
1923 {
1924 /* check that the code field contains 16 bits */
1925 if (strlen (p->code) != 16)
1926 {
1927 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1928 p->code, strlen (p->code), p->name);
1929 abort ();
1930 }
1931 }
1932 }
1933
1934 /* now generate the requested data */
594266fc
SC
1935 if (ac > 1)
1936 {
1937 if (strcmp (av[1], "-t") == 0)
1938 {
1939 gengastab ();
1940 }
acae2683
TG
1941 else if (strcmp (av[1], "-d") == 0)
1942 {
1943 gendefines ();
1944 }
594266fc
SC
1945 else if (strcmp (av[1], "-s") == 0)
1946 {
1947 filltable ();
1948 dumptable ();
1949
1950 }
1951 else if (strcmp (av[1], "-x") == 0)
1952 {
1953 filltable ();
1954 gensim ();
1955 }
1956 }
1957 else
1958 {
1959 genopc ();
1960 }
1961 return 0;
1962}