Shared libraries are not supported on MS-DOS.
[binutils-gdb.git] / sim / sh / gencode.c
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
26 -d generates a define table
27 -x generates the simulator code switch statement
28 default generates the opcode tables
29
30 */
31
32 #include <stdio.h>
33
34 #define MAX_NR_STUFF 20
35
36 typedef struct
37 {
38 char *defs;
39 char *refs;
40 char *name;
41 char *code;
42 char *stuff[MAX_NR_STUFF];
43 int index;
44 }
45
46 op;
47
48
49 op tab[] =
50 {
51
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 /* sh4 */
248 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
249 "if (! FPSCR_PR || n & 1)",
250 " saved_state.asregs.exception = SIGILL;",
251 "else",
252 "{",
253 " union",
254 " {",
255 " int i;",
256 " float f;",
257 " } u;",
258 " u.f = DR(n);",
259 " FPUL = u.i;",
260 "}",
261 },
262
263 /* sh4 */
264 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
265 "if (! FPSCR_PR || n & 1)",
266 " saved_state.asregs.exception = SIGILL;",
267 "else",
268 "{",
269 " union",
270 " {",
271 " int i;",
272 " float f;",
273 " } u;",
274 " u.i = FPUL;",
275 " SET_DR(n, u.f);",
276 "}",
277 },
278
279 /* sh3e */
280 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
281 "FP_OP (n, /, m);",
282 "/* FIXME: check for DP and (n & 1) == 0? */",
283 },
284
285 /* sh4 */
286 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
287 "/* FIXME: not implemented */",
288 "saved_state.asregs.exception = SIGILL;",
289 "/* FIXME: check for DP and (n & 1) == 0? */",
290 },
291
292 /* sh3e */
293 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
294 "SET_FR (n, (float)0.0);",
295 "/* FIXME: check for DP and (n & 1) == 0? */",
296 },
297
298 /* sh3e */
299 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
300 "SET_FR (n, (float)1.0);",
301 "/* FIXME: check for DP and (n & 1) == 0? */",
302 },
303
304 /* sh3e */
305 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
306 " union",
307 " {",
308 " int i;",
309 " float f;",
310 " } u;",
311 " u.f = FR(n);",
312 " FPUL = u.i;",
313 },
314
315 /* sh3e */
316 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
317 /* sh4 */
318 "if (FPSCR_PR)",
319 " SET_DR (n, (double)FPUL);",
320 "else",
321 "{",
322 " SET_FR (n, (float)FPUL);",
323 "}",
324 },
325
326 /* sh3e */
327 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
328 "SET_FR (n, FR(m) * FR(0) + FR(n));",
329 "/* FIXME: check for DP and (n & 1) == 0? */",
330 },
331
332 /* sh3e */
333 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
334 /* sh4 */
335 "if (FPSCR_SZ) {",
336 " int ni = XD_TO_XF (n);",
337 " int mi = XD_TO_XF (m);",
338 " SET_XF (ni + 0, XF (mi + 0));",
339 " SET_XF (ni + 1, XF (mi + 1));",
340 "}",
341 "else",
342 "{",
343 " SET_FR (n, FR (m));",
344 "}",
345 },
346 /* sh3e */
347 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
348 /* sh4 */
349 "if (FPSCR_SZ) {",
350 " MA (2);",
351 " WDAT (R[n], m);",
352 "}",
353 "else",
354 "{",
355 " MA (1);",
356 " WLAT (R[n], FI(m));",
357 "}",
358 },
359 /* sh3e */
360 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
361 /* sh4 */
362 "if (FPSCR_SZ) {",
363 " MA (2);",
364 " RDAT (R[m], n);",
365 "}",
366 "else",
367 "{",
368 " MA (1);",
369 " SET_FI(n, RLAT(R[m]));",
370 "}",
371 },
372 /* sh3e */
373 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
374 /* sh4 */
375 "if (FPSCR_SZ) {",
376 " MA (2);",
377 " RDAT (R[m], n);",
378 " R[m] += 8;",
379 "}",
380 "else",
381 "{",
382 " MA (1);",
383 " SET_FI (n, RLAT (R[m]));",
384 " R[m] += 4;",
385 "}",
386 },
387 /* sh3e */
388 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
389 /* sh4 */
390 "if (FPSCR_SZ) {",
391 " MA (2);",
392 " R[n] -= 8;",
393 " WDAT (R[n], m);",
394 "}",
395 "else",
396 "{",
397 " MA (1);",
398 " R[n] -= 4;",
399 " WLAT (R[n], FI(m));",
400 "}",
401 },
402 /* sh3e */
403 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
404 /* sh4 */
405 "if (FPSCR_SZ) {",
406 " MA (2);",
407 " RDAT (R[0]+R[m], n);",
408 "}",
409 "else",
410 "{",
411 " MA (1);",
412 " SET_FI(n, RLAT(R[0] + R[m]));",
413 "}",
414 },
415 /* sh3e */
416 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
417 /* sh4 */
418 "if (FPSCR_SZ) {",
419 " MA (2);",
420 " WDAT (R[0]+R[n], m);",
421 "}",
422 "else",
423 "{",
424 " MA (1);",
425 " WLAT((R[0]+R[n]), FI(m));",
426 "}",
427 },
428
429 /* sh4: See fmov instructions above for move to/from extended fp registers */
430
431 /* sh3e */
432 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
433 "FP_OP(n, *, m);",
434 },
435
436 /* sh3e */
437 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
438 "FP_UNARY(n, -);",
439 },
440
441 /* sh4 */
442 { "", "", "frchg", "1111101111111101",
443 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
444 },
445
446 /* sh4 */
447 { "", "", "fschg", "1111001111111101",
448 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
449 },
450
451 /* sh3e */
452 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
453 "FP_UNARY(n, sqrt);",
454 },
455
456 /* sh3e */
457 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
458 "FP_OP(n, -, m);",
459 },
460
461 /* sh3e */
462 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
463 /* sh4 */
464 "if (FPSCR_PR) {",
465 " if (DR(n) != DR(n)) /* NaN */",
466 " FPUL = 0x80000000;",
467 " else",
468 " FPUL = (int)DR(n);",
469 "}",
470 "else",
471 "if (FR(n) != FR(n)) /* NaN */",
472 " FPUL = 0x80000000;",
473 "else",
474 " FPUL = (int)FR(n);",
475 },
476
477 /* sh3e */
478 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
479 " union",
480 " {",
481 " int i;",
482 " float f;",
483 " } u;",
484 " u.i = FPUL;",
485 " SET_FR (n, u.f);",
486 },
487
488 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
489 "nia = R[n];",
490 "Delay_Slot (PC + 2);",
491 },
492
493 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
494 "PR = PC + 4;",
495 "nia = R[n];",
496 "if (~doprofile)",
497 " gotcall (PR, nia);",
498 "Delay_Slot (PC + 2);",
499 },
500
501 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
502 "GBR = R[n];",
503 "/* FIXME: user mode */",
504 },
505 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
506 "SET_SR (R[n]);",
507 "/* FIXME: user mode */",
508 },
509 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
510 "VBR = R[n];",
511 "/* FIXME: user mode */",
512 },
513 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
514 "SSR = R[n];",
515 "/* FIXME: user mode */",
516 },
517 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
518 "SPC = R[n];",
519 "/* FIXME: user mode */",
520 },
521 #if 0
522 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
523 "DBR = R[n];",
524 "/* FIXME: user mode */",
525 },
526 #endif
527 { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
528 "SET_Rn_BANK (0, R[n]);",
529 "/* FIXME: user mode */",
530 },
531 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
532 "SET_Rn_BANK (1, R[n]);",
533 "/* FIXME: user mode */",
534 },
535 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
536 "SET_Rn_BANK (2, R[n]);",
537 "/* FIXME: user mode */",
538 },
539 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
540 "SET_Rn_BANK (3, R[n]);",
541 "/* FIXME: user mode */",
542 },
543 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
544 "SET_Rn_BANK (4, R[n]);",
545 "/* FIXME: user mode */",
546 },
547 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
548 "SET_Rn_BANK (5, R[n]);",
549 "/* FIXME: user mode */",
550 },
551 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
552 "SET_Rn_BANK (6, R[n]);",
553 "/* FIXME: user mode */",
554 },
555 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
556 "SET_Rn_BANK (7, R[n]);",
557 "/* FIXME: user mode */",
558 },
559 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
560 "MA (1);",
561 "GBR = RLAT (R[n]);",
562 "R[n] += 4;",
563 "/* FIXME: user mode */",
564 },
565 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
566 "MA (1);",
567 "SET_SR (RLAT (R[n]));",
568 "R[n] += 4;",
569 "/* FIXME: user mode */",
570 },
571 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
572 "MA (1);",
573 "VBR = RLAT (R[n]);",
574 "R[n] += 4;",
575 "/* FIXME: user mode */",
576 },
577 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
578 "MA (1);",
579 "SSR = RLAT (R[n]);",
580 "R[n] += 4;",
581 "/* FIXME: user mode */",
582 },
583 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
584 "MA (1);",
585 "SPC = RLAT (R[n]);",
586 "R[n] += 4;",
587 "/* FIXME: user mode */",
588 },
589 #if 0
590 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
591 "MA (1);",
592 "DBR = RLAT (R[n]);",
593 "R[n] += 4;",
594 "/* FIXME: user mode */",
595 },
596 #endif
597 { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
598 "MA (1);",
599 "SET_Rn_BANK (0, RLAT (R[n]));",
600 "R[n] += 4;",
601 "/* FIXME: user mode */",
602 },
603 { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
604 "MA (1);",
605 "SET_Rn_BANK (1, RLAT (R[n]));",
606 "R[n] += 4;",
607 "/* FIXME: user mode */",
608 },
609 { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
610 "MA (1);",
611 "SET_Rn_BANK (2, RLAT (R[n]));",
612 "R[n] += 4;",
613 "/* FIXME: user mode */",
614 },
615 { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
616 "MA (1);",
617 "SET_Rn_BANK (3, RLAT (R[n]));",
618 "R[n] += 4;",
619 "/* FIXME: user mode */",
620 },
621 { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
622 "MA (1);",
623 "SET_Rn_BANK (4, RLAT (R[n]));",
624 "R[n] += 4;",
625 "/* FIXME: user mode */",
626 },
627 { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
628 "MA (1);",
629 "SET_Rn_BANK (5, RLAT (R[n]));",
630 "R[n] += 4;",
631 "/* FIXME: user mode */",
632 },
633 { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
634 "MA (1);",
635 "SET_Rn_BANK (6, RLAT (R[n]));",
636 "R[n] += 4;",
637 "/* FIXME: user mode */",
638 },
639 { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
640 "MA (1);",
641 "SET_Rn_BANK (7, RLAT (R[n]));",
642 "R[n] += 4;",
643 "/* FIXME: user mode */",
644 },
645
646 /* sh3e */
647 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
648 "FPUL = R[n];",
649 },
650 /* sh3e */
651 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
652 "MA (1);",
653 "FPUL = RLAT(R[n]);",
654 "R[n] += 4;",
655 },
656 /* sh3e */
657 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
658 "SET_FPSCR(R[n]);",
659 },
660 /* sh3e */
661 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
662 "MA (1);",
663 "SET_FPSCR (RLAT(R[n]));",
664 "R[n] += 4;",
665 },
666
667 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
668 "MACH = R[n];",
669 },
670 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
671 "MACL= R[n];",
672 },
673 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
674 "PR = R[n];",
675 },
676 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
677 "MA (1);",
678 "MACH = SEXT(RLAT(R[n]));",
679 "R[n]+=4;",
680 },
681 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
682 "MA (1);",
683 "MACL = RLAT(R[n]);",
684 "R[n]+=4;",
685 },
686 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
687 "MA (1);",
688 "PR = RLAT(R[n]);",
689 "R[n]+=4;;",
690 },
691
692 { "", "", "ldtlb", "0000000000111000",
693 "/* FIXME: XXX*/ abort();",
694 },
695
696 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
697 "trap (255,R0,memory,maskl,maskw,little_endian);",
698 "/* FIXME: mac.l support */",
699 },
700
701 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
702 "macw(R0,memory,n,m);",
703 },
704
705 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
706 "R[n] = SEXT(i);",
707 },
708 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
709 "R[n] = R[m];",
710 },
711
712 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
713 "MA (1);",
714 "R0 = RSBAT (i + GBR);",
715 "L (0);",
716 },
717 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
718 "MA (1);",
719 "R0 = RSBAT (i + R[m]);",
720 "L (0);",
721 },
722 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
723 "MA (1);",
724 "R[n] = RSBAT (R0 + R[m]);",
725 "L (n);",
726 },
727 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
728 "MA (1);",
729 "R[n] = RSBAT (R[m]);",
730 "R[m] += 1;",
731 "L (n);",
732 },
733 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
734 "MA (1);",
735 "WBAT (R[n], R[m]);",
736 },
737 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
738 "MA (1);",
739 "WBAT (i + GBR, R0);",
740 },
741 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
742 "MA (1);",
743 "WBAT (i + R[m], R0);",
744 },
745 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
746 "MA (1);",
747 "WBAT (R[n] + R0, R[m]);",
748 },
749 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
750 "MA (1);",
751 "R[n] -= 1;",
752 "WBAT (R[n], R[m]);",
753 },
754 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
755 "MA (1);",
756 "R[n] = RSBAT (R[m]);",
757 "L (n);",
758 },
759
760 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
761 "MA (1);",
762 "R0 = RLAT (i + GBR);",
763 "L (0);",
764 },
765 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
766 "MA (1);",
767 "R[n] = RLAT((PC & ~3) + 4 + i);",
768 "L (n);",
769 },
770 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
771 "MA (1);",
772 "R[n] = RLAT (i + R[m]);",
773 "L (n);",
774 },
775 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
776 "MA (1);",
777 "R[n] = RLAT (R0 + R[m]);",
778 "L (n);",
779 },
780 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
781 "MA (1);",
782 "R[n] = RLAT (R[m]);",
783 "R[m] += 4;",
784 "L (n);",
785 },
786 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
787 "MA (1);",
788 "R[n] = RLAT (R[m]);",
789 "L (n);",
790 },
791 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
792 "MA (1);",
793 "WLAT (i + GBR, R0);",
794 },
795 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
796 "MA (1);",
797 "WLAT (i + R[n], R[m]);",
798 },
799 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
800 "MA (1);",
801 "WLAT (R0 + R[n], R[m]);",
802 },
803 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
804 "MA (1) ;",
805 "R[n] -= 4;",
806 "WLAT (R[n], R[m]);",
807 },
808 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
809 "MA (1);",
810 "WLAT (R[n], R[m]);",
811 },
812
813 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
814 "MA (1)",
815 ";R0 = RSWAT (i + GBR);",
816 "L (0);",
817 },
818 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
819 "MA (1);",
820 "R[n] = RSWAT (PC + 4 + i);",
821 "L (n);",
822 },
823 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
824 "MA (1);",
825 "R0 = RSWAT (i + R[m]);",
826 "L (0);",
827 },
828 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
829 "MA (1);",
830 "R[n] = RSWAT (R0 + R[m]);",
831 "L (n);",
832 },
833 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
834 "MA (1);",
835 "R[n] = RSWAT (R[m]);",
836 "R[m] += 2;",
837 "L (n);",
838 },
839 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
840 "MA (1);",
841 "R[n] = RSWAT (R[m]);",
842 "L (n);",
843 },
844 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
845 "MA (1);",
846 "WWAT (i + GBR, R0);",
847 },
848 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
849 "MA (1);",
850 "WWAT (i + R[m], R0);",
851 },
852 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
853 "MA (1);",
854 "WWAT (R0 + R[n], R[m]);",
855 },
856 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
857 "MA (1);",
858 "R[n] -= 2;",
859 "WWAT (R[n], R[m]);",
860 },
861 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
862 "MA (1);",
863 "WWAT (R[n], R[m]);",
864 },
865
866 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
867 "R0 = ((i + 4 + PC) & ~0x3);",
868 },
869
870 { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
871 "/* FIXME: Not implemented */",
872 "saved_state.asregs.exception = SIGILL;",
873 },
874
875 { "n", "", "movt <REG_N>", "0000nnnn00101001",
876 "R[n] = T;",
877 },
878
879 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
880 "MACL = ((int)R[n]) * ((int)R[m]);",
881 },
882 #if 0
883 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
884 "MACL = R[n] * R[m];",
885 },
886 #endif
887
888 /* muls.w - see muls */
889 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
890 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
891 },
892
893 /* mulu.w - see mulu */
894 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
895 "MACL = (((unsigned int)(unsigned short)R[n])",
896 " * ((unsigned int)(unsigned short)R[m]));",
897 },
898
899 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
900 "R[n] = - R[m];",
901 },
902
903 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
904 "ult = -T;",
905 "SET_SR_T (ult > 0);",
906 "R[n] = ult - R[m];",
907 "SET_SR_T (T || (R[n] > ult));",
908 },
909
910 { "", "", "nop", "0000000000001001",
911 "/* nop */",
912 },
913
914 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
915 "R[n] = ~R[m];",
916 },
917
918 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
919 "/* FIXME: Not implemented */",
920 "saved_state.asregs.exception = SIGILL;",
921 },
922
923 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
924 "/* FIXME: Not implemented */",
925 "saved_state.asregs.exception = SIGILL;",
926 },
927
928 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
929 "RSBAT (R[n]); /* Take exceptions like byte load. */",
930 "/* FIXME: Cache not implemented */",
931 },
932
933 { "0", "", "or #<imm>,R0", "11001011i8*1....",
934 "R0 |= i;",
935 },
936 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
937 "R[n] |= R[m];",
938 },
939 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
940 "MA (1);",
941 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
942 },
943
944 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
945 "/* Except for the effect on the cache - which is not simulated -",
946 " this is like a nop. */",
947 },
948
949 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
950 "ult = R[n] < 0;",
951 "R[n] = (R[n] << 1) | T;",
952 "SET_SR_T (ult);",
953 },
954
955 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
956 "ult = R[n] & 1;",
957 "R[n] = (UR[n] >> 1) | (T << 31);",
958 "SET_SR_T (ult);",
959 },
960
961 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
962 "SET_SR_T (R[n] < 0);",
963 "R[n] <<= 1;",
964 "R[n] |= T;",
965 },
966
967 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
968 "SET_SR_T (R[n] & 1);",
969 "R[n] = UR[n] >> 1;",
970 "R[n] |= (T << 31);",
971 },
972
973 { "", "", "rte", "0000000000101011",
974 #if 0
975 /* SH-[12] */
976 "int tmp = PC;",
977 "nia = RLAT (R[15]) + 2;",
978 "R[15] += 4;",
979 "SET_SR (RLAT (R[15]) & 0x3f3);",
980 "R[15] += 4;",
981 "Delay_Slot (PC + 2);",
982 #else
983 "nia = SPC;",
984 "SET_SR (SSR);",
985 "Delay_Slot (PC + 2);",
986 #endif
987 },
988
989 { "", "", "rts", "0000000000001011",
990 "nia = PR;",
991 "Delay_Slot (PC + 2);",
992 },
993
994 { "", "", "sets", "0000000001011000",
995 "SET_SR_S (1);",
996 },
997
998 { "", "", "sett", "0000000000011000",
999 "SET_SR_T (1);",
1000 },
1001
1002 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1003 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
1004 },
1005
1006 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1007 "SET_SR_T (R[n] < 0);",
1008 "R[n] <<= 1;",
1009 },
1010
1011 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1012 "SET_SR_T (R[n] & 1);",
1013 "R[n] = R[n] >> 1;",
1014 },
1015
1016 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1017 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
1018 },
1019
1020 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1021 "SET_SR_T (R[n] < 0);",
1022 "R[n] <<= 1;",
1023 },
1024
1025 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1026 "R[n] <<= 2;",
1027 },
1028 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1029 "R[n] <<= 8;",
1030 },
1031 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1032 "R[n] <<= 16;",
1033 },
1034
1035 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1036 "SET_SR_T (R[n] & 1);",
1037 "R[n] = UR[n] >> 1;",
1038 },
1039
1040 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1041 "R[n] = UR[n] >> 2;",
1042 },
1043 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1044 "R[n] = UR[n] >> 8;",
1045 },
1046 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1047 "R[n] = UR[n] >> 16;",
1048 },
1049
1050 { "", "", "sleep", "0000000000011011",
1051 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
1052 "nia = PC;",
1053 },
1054
1055 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
1056 "R[n] = GBR;",
1057 },
1058 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
1059 "R[n] = GET_SR ();",
1060 },
1061 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
1062 "R[n] = VBR;",
1063 },
1064 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
1065 "R[n] = SSR;",
1066 },
1067 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
1068 "R[n] = SPC;",
1069 },
1070 #if 0
1071 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1072 "R[n] = SGR;",
1073 },
1074 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1075 "R[n] = DBR;",
1076 },
1077 #endif
1078 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
1079 "R[n] = Rn_BANK (0);",
1080 },
1081 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
1082 "R[n] = Rn_BANK (1);",
1083 },
1084 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
1085 "R[n] = Rn_BANK (2);",
1086 },
1087 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
1088 "R[n] = Rn_BANK (3);",
1089 },
1090 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
1091 "R[n] = Rn_BANK (4);",
1092 },
1093 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
1094 "R[n] = Rn_BANK (5);",
1095 },
1096 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
1097 "R[n] = Rn_BANK (6);",
1098 },
1099 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
1100 "R[n] = Rn_BANK (7);",
1101 },
1102 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
1103 "MA (1);",
1104 "R[n] -= 4;",
1105 "WLAT (R[n], GBR);;",
1106 },
1107 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
1108 "MA (1);",
1109 "R[n] -= 4;",
1110 "WLAT (R[n], GET_SR());",
1111 },
1112 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
1113 "MA (1);",
1114 "R[n] -= 4;",
1115 "WLAT (R[n], VBR);",
1116 },
1117 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
1118 "MA (1);",
1119 "R[n] -= 4;",
1120 "WLAT (R[n], SSR);",
1121 },
1122 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
1123 "MA (1);",
1124 "R[n] -= 4;",
1125 "WLAT (R[n], SPC);",
1126 },
1127 #if 0
1128 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1129 "MA (1);",
1130 "R[n] -= 4;",
1131 "WLAT (R[n], SGR);",
1132 },
1133 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1134 "MA (1);",
1135 "R[n] -= 4;",
1136 "WLAT (R[n], DBR);",
1137 },
1138 #endif
1139 { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
1140 "MA (1);",
1141 "R[n] -= 4;",
1142 "WLAT (R[n], Rn_BANK (0));",
1143 },
1144 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
1145 "MA (1);",
1146 "R[n] -= 4;",
1147 "WLAT (R[n], Rn_BANK (1));",
1148 },
1149 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
1150 "MA (1);",
1151 "R[n] -= 4;",
1152 "WLAT (R[n], Rn_BANK (2));",
1153 },
1154 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
1155 "MA (1);",
1156 "R[n] -= 4;",
1157 "WLAT (R[n], Rn_BANK (3));",
1158 },
1159 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
1160 "MA (1);",
1161 "R[n] -= 4;",
1162 "WLAT (R[n], Rn_BANK (4));",
1163 },
1164 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
1165 "MA (1);",
1166 "R[n] -= 4;",
1167 "WLAT (R[n], Rn_BANK (5));",
1168 },
1169 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1170 "MA (1);",
1171 "R[n] -= 4;",
1172 "WLAT (R[n], Rn_BANK (6));",
1173 },
1174 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1175 "MA (1);",
1176 "R[n] -= 4;",
1177 "WLAT (R[n], Rn_BANK (7));",
1178 },
1179
1180 /* sh3e */
1181 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1182 "R[n] = FPUL;",
1183 },
1184 /* sh3e */
1185 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1186 "MA (1);",
1187 "R[n] -= 4;",
1188 "WLAT (R[n], FPUL);",
1189 },
1190 /* sh3e */
1191 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1192 "R[n] = GET_FPSCR ();",
1193 },
1194 /* sh3e */
1195 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1196 "MA (1);",
1197 "R[n] -= 4;",
1198 "WLAT (R[n], GET_FPSCR ());",
1199 },
1200
1201 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1202 "R[n] = MACH;",
1203 },
1204 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1205 "R[n] = MACL;",
1206 },
1207 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1208 "R[n] = PR;",
1209 },
1210 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1211 "MA (1);",
1212 "R[n] -= 4;",
1213 "WLAT (R[n], MACH);",
1214 },
1215 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1216 "MA (1);",
1217 "R[n] -= 4;",
1218 "WLAT (R[n], MACL);",
1219 },
1220 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1221 "MA (1);",
1222 "R[n] -= 4;",
1223 "WLAT (R[n], PR);",
1224 },
1225
1226 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1227 "R[n] -= R[m];",
1228 },
1229
1230 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1231 "ult = R[n] - T;",
1232 "SET_SR_T (ult > R[n]);",
1233 "R[n] = ult - R[m];",
1234 "SET_SR_T (T || (R[n] > ult));",
1235 },
1236
1237 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1238 "ult = R[n] - R[m];",
1239 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1240 "R[n] = ult;",
1241 },
1242
1243 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1244 "R[n] = ((R[m] & 0xffff0000)",
1245 " | ((R[m] << 8) & 0xff00)",
1246 " | ((R[m] >> 8) & 0x00ff));",
1247 },
1248 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1249 "R[n] = (((R[m] << 16) & 0xffff0000)",
1250 " | ((R[m] >> 16) & 0x00ffff));",
1251 },
1252
1253 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1254 "MA (1);",
1255 "ult = RBAT(R[n]);",
1256 "SET_SR_T (ult == 0);",
1257 "WBAT(R[n],ult|0x80);",
1258 },
1259
1260 { "0", "", "trapa #<imm>", "11000011i8*1....",
1261 #if 0
1262 /* SH-[12] */
1263 "long imm = 0xff & i;",
1264 "if (i==0xc3)",
1265 " PC-=2;",
1266 "if (i<20||i==34||i==0xc3)",
1267 " trap(i,R,memory,maskl,maskw,little_endian);",
1268 "else {",
1269 " R[15]-=4;",
1270 " WLAT(R[15],GET_SR());",
1271 " R[15]-=4;",
1272 " WLAT(R[15],PC+2);",
1273 " PC=RLAT(VBR+(imm<<2))-2;",
1274 "}",
1275 #else
1276 "if (i == 0xc3)",
1277 " {",
1278 " nia = PC;",
1279 " trap (i, R, memory, maskl, maskw, little_endian);",
1280 " }",
1281 "else if (i < 20 || i==34 || i==0xc3)",
1282 " trap (i, R, memory, maskl, maskw, little_endian);",
1283 "else if (!SR_BL) {",
1284 " /* FIXME: TRA = (imm << 2); */",
1285 " SSR = GET_SR();",
1286 " SPC = PC + 2;",
1287 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1288 " /* FIXME: EXPEVT = 0x00000160; */",
1289 " nia = VBR + 0x00000100;",
1290 "}",
1291 #endif
1292 },
1293
1294 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1295 "SET_SR_T ((R[n] & R[m]) == 0);",
1296 },
1297 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1298 "SET_SR_T ((R0 & i) == 0);",
1299 },
1300 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1301 "MA (1);",
1302 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1303 },
1304
1305 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1306 "R0 ^= i;",
1307 },
1308 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1309 "R[n] ^= R[m];",
1310 },
1311 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1312 "MA (1);",
1313 "ult = RBAT (GBR+R0);",
1314 "ult ^= i;",
1315 "WBAT (GBR + R0, ult);",
1316 },
1317
1318 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1319 "R[n] = (((R[n] >> 16) & 0xffff)",
1320 " | ((R[m] << 16) & 0xffff0000));",
1321 },
1322
1323 #if 0
1324 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1325 "divl(0,R[n],R[m]);",
1326 },
1327 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1328 "divl(0,R[n],R[m]);",
1329 },
1330 #endif
1331
1332 {0, 0}};
1333
1334 /* Tables of things to put into enums for sh-opc.h */
1335 static char *nibble_type_list[] =
1336 {
1337 "HEX_0",
1338 "HEX_1",
1339 "HEX_2",
1340 "HEX_3",
1341 "HEX_4",
1342 "HEX_5",
1343 "HEX_6",
1344 "HEX_7",
1345 "HEX_8",
1346 "HEX_9",
1347 "HEX_A",
1348 "HEX_B",
1349 "HEX_C",
1350 "HEX_D",
1351 "HEX_E",
1352 "HEX_F",
1353 "REG_N",
1354 "REG_M",
1355 "BRANCH_12",
1356 "BRANCH_8",
1357 "DISP_8",
1358 "DISP_4",
1359 "IMM_4",
1360 "IMM_4BY2",
1361 "IMM_4BY4",
1362 "PCRELIMM_8BY2",
1363 "PCRELIMM_8BY4",
1364 "IMM_8",
1365 "IMM_8BY2",
1366 "IMM_8BY4",
1367 0
1368 };
1369 static
1370 char *arg_type_list[] =
1371 {
1372 "A_END",
1373 "A_BDISP12",
1374 "A_BDISP8",
1375 "A_DEC_M",
1376 "A_DEC_N",
1377 "A_DISP_GBR",
1378 "A_DISP_PC",
1379 "A_DISP_REG_M",
1380 "A_DISP_REG_N",
1381 "A_GBR",
1382 "A_IMM",
1383 "A_INC_M",
1384 "A_INC_N",
1385 "A_IND_M",
1386 "A_IND_N",
1387 "A_IND_R0_REG_M",
1388 "A_IND_R0_REG_N",
1389 "A_MACH",
1390 "A_MACL",
1391 "A_PR",
1392 "A_R0",
1393 "A_R0_GBR",
1394 "A_REG_M",
1395 "A_REG_N",
1396 "A_SR",
1397 "A_VBR",
1398 "A_SSR",
1399 "A_SPC",
1400 0,
1401 };
1402
1403 static void
1404 make_enum_list (name, s)
1405 char *name;
1406 char **s;
1407 {
1408 int i = 1;
1409 printf ("typedef enum {\n");
1410 while (*s)
1411 {
1412 printf ("\t%s,\n", *s);
1413 s++;
1414 i++;
1415 }
1416 printf ("} %s;\n", name);
1417 }
1418
1419 static int
1420 qfunc (a, b)
1421 op *a;
1422 op *b;
1423 {
1424 char bufa[9];
1425 char bufb[9];
1426 memcpy (bufa, a->code, 4);
1427 memcpy (bufa + 4, a->code + 12, 4);
1428 bufa[8] = 0;
1429
1430 memcpy (bufb, b->code, 4);
1431 memcpy (bufb + 4, b->code + 12, 4);
1432 bufb[8] = 0;
1433 return (strcmp (bufa, bufb));
1434 }
1435
1436 static void
1437 sorttab ()
1438 {
1439 op *p = tab;
1440 int len = 0;
1441
1442 while (p->name)
1443 {
1444 p++;
1445 len++;
1446 }
1447 qsort (tab, len, sizeof (*p), qfunc);
1448 }
1449
1450 static void
1451 printonmatch (ptr, a, rep)
1452 char **ptr;
1453 char *a;
1454 char *rep;
1455 {
1456 int l = strlen (a);
1457 if (strncmp (*ptr, a, l) == 0)
1458 {
1459 printf ("%s", rep);
1460 *ptr += l;
1461 if (**ptr)
1462 printf (",");
1463 }
1464 }
1465
1466
1467 static
1468 void
1469 think (o)
1470 op *o;
1471 {
1472 char *n;
1473 char *p;
1474
1475 printf ("{\"");
1476 n = o->name;
1477 while (*n && *n != ' ')
1478 {
1479 printf ("%c", *n);
1480 n++;
1481 }
1482 printf ("\",{");
1483
1484 p = n;
1485
1486 if (!*p)
1487 {
1488 printf ("0");
1489 }
1490 while (*p)
1491 {
1492 while (*p == ',' || *p == ' ')
1493 p++;
1494 printonmatch (&p, "#<imm>", "A_IMM");
1495 printonmatch (&p, "R0", "A_R0");
1496 printonmatch (&p, "<REG_N>", "A_REG_N");
1497 printonmatch (&p, "@<REG_N>+", "A_INC_N");
1498 printonmatch (&p, "@<REG_N>", "A_IND_N");
1499 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
1500 printonmatch (&p, "<REG_M>", " A_REG_M");
1501 printonmatch (&p, "@<REG_M>+", "A_INC_M");
1502 printonmatch (&p, "@<REG_M>", "A_IND_M");
1503 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
1504 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
1505 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1506 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1507 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1508 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1509 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
1510 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
1511 printonmatch (&p, "<bdisp8>", "A_BDISP8");
1512 printonmatch (&p, "<bdisp12>", "A_BDISP12");
1513 printonmatch (&p, "SR", "A_SR");
1514 printonmatch (&p, "GBR", "A_GBR");
1515 printonmatch (&p, "VBR", "A_VBR");
1516 printonmatch (&p, "SSR", "A_SSR");
1517 printonmatch (&p, "SPC", "A_SPC");
1518 printonmatch (&p, "MACH", "A_MACH");
1519 printonmatch (&p, "MACL", "A_MACL");
1520 printonmatch (&p, "PR", "A_PR");
1521
1522 }
1523 printf ("},{");
1524
1525 p = o->code;
1526 while (*p)
1527 {
1528 printonmatch (&p, "0000", "HEX_0");
1529 printonmatch (&p, "0001", "HEX_1");
1530 printonmatch (&p, "0010", "HEX_2");
1531 printonmatch (&p, "0011", "HEX_3");
1532 printonmatch (&p, "0100", "HEX_4");
1533 printonmatch (&p, "0101", "HEX_5");
1534 printonmatch (&p, "0110", "HEX_6");
1535 printonmatch (&p, "0111", "HEX_7");
1536
1537 printonmatch (&p, "1000", "HEX_8");
1538 printonmatch (&p, "1001", "HEX_9");
1539 printonmatch (&p, "1010", "HEX_A");
1540 printonmatch (&p, "1011", "HEX_B");
1541 printonmatch (&p, "1100", "HEX_C");
1542 printonmatch (&p, "1101", "HEX_D");
1543 printonmatch (&p, "1110", "HEX_E");
1544 printonmatch (&p, "1111", "HEX_F");
1545 printonmatch (&p, "i8*1....", "IMM_8");
1546 printonmatch (&p, "i4*1", "IMM_4");
1547 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
1548 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
1549 printonmatch (&p, "i8*2....", "IMM_8BY2");
1550 printonmatch (&p, "i4*2", "IMM_4BY2");
1551 printonmatch (&p, "i8*4....", "IMM_8BY4");
1552 printonmatch (&p, "i4*4", "IMM_4BY4");
1553 printonmatch (&p, "i12.........", "BRANCH_12");
1554 printonmatch (&p, "i8p1....", "BRANCH_8");
1555 printonmatch (&p, "nnnn", "REG_N");
1556 printonmatch (&p, "mmmm", "REG_M");
1557
1558 }
1559 printf ("}},\n");
1560 }
1561
1562 static void
1563 gengastab ()
1564 {
1565 op *p;
1566 sorttab ();
1567 for (p = tab; p->name; p++)
1568 {
1569 printf ("%s %-30s\n", p->code, p->name);
1570 }
1571
1572
1573 }
1574
1575
1576 static void
1577 genopc ()
1578 {
1579 op *p;
1580 make_enum_list ("sh_nibble_type", nibble_type_list);
1581 make_enum_list ("sh_arg_type", arg_type_list);
1582
1583 printf ("typedef struct {\n");
1584 printf ("char *name;\n");
1585 printf ("sh_arg_type arg[3];\n");
1586 printf ("sh_nibble_type nibbles[4];\n");
1587 printf ("} sh_opcode_info;\n");
1588 printf ("#ifdef DEFINE_TABLE\n");
1589 printf ("sh_opcode_info sh_table[]={\n");
1590 for (p = tab; p->name; p++)
1591 {
1592 printf ("\n/* %s %-20s*/", p->code, p->name);
1593 think (p);
1594 }
1595 printf ("0};\n");
1596 printf ("#endif\n");
1597 }
1598
1599
1600
1601
1602
1603
1604 /* Convert a string of 4 binary digits into an int */
1605
1606 static
1607 int
1608 bton (s)
1609 char *s;
1610
1611 {
1612 int n = 0;
1613 int v = 8;
1614 while (v)
1615 {
1616 if (*s == '1')
1617 n |= v;
1618 v >>= 1;
1619 s++;
1620 }
1621 return n;
1622 }
1623
1624 static unsigned char table[1 << 16];
1625
1626 /* Take an opcode expand all varying fields in it out and fill all the
1627 right entries in 'table' with the opcode index*/
1628
1629 static void
1630 expand_opcode (shift, val, i, s)
1631 int shift;
1632 int val;
1633 int i;
1634 char *s;
1635 {
1636 int j;
1637
1638 if (*s == 0)
1639 {
1640 table[val] = i;
1641 }
1642 else
1643 {
1644 switch (s[0])
1645 {
1646
1647 case '0':
1648 case '1':
1649 {
1650
1651 int n = bton (s);
1652 if (n >= 0)
1653 {
1654 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1655 }
1656 break;
1657 }
1658 case 'n':
1659 case 'm':
1660 for (j = 0; j < 16; j++)
1661 {
1662 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1663
1664 }
1665 break;
1666
1667 default:
1668 for (j = 0; j < (1 << (shift + 4)); j++)
1669 {
1670 table[val | j] = i;
1671 }
1672 }
1673 }
1674 }
1675
1676 /* Print the jump table used to index an opcode into a switch
1677 statement entry. */
1678
1679 static void
1680 dumptable ()
1681 {
1682 int lump = 256;
1683 int online = 16;
1684
1685 int i = 0;
1686
1687 while (i < 1 << 16)
1688 {
1689 int j = 0;
1690
1691 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1692
1693 while (j < lump)
1694 {
1695 int k = 0;
1696 while (k < online)
1697 {
1698 printf ("%2d", table[i + j + k]);
1699 if (j + k < lump)
1700 printf (",");
1701
1702 k++;
1703 }
1704 j += k;
1705 printf ("\n");
1706 }
1707 i += j;
1708 printf ("};\n");
1709 }
1710
1711 }
1712
1713
1714 static void
1715 filltable ()
1716 {
1717 op *p;
1718 int index = 1;
1719
1720 sorttab ();
1721 for (p = tab; p->name; p++)
1722 {
1723 p->index = index++;
1724 expand_opcode (12, 0, p->index, p->code);
1725 }
1726 }
1727
1728 static void
1729 gensim ()
1730 {
1731 op *p;
1732 int j;
1733
1734 printf ("{\n");
1735 printf (" switch (jump_table[iword]) {\n");
1736
1737 for (p = tab; p->name; p++)
1738 {
1739 int sextbit = -1;
1740 int needm = 0;
1741 int needn = 0;
1742
1743 char *s = p->code;
1744
1745 printf (" /* %s %s */\n", p->name, p->code);
1746 printf (" case %d: \n", p->index);
1747
1748 printf (" {\n");
1749 while (*s)
1750 {
1751 switch (*s)
1752 {
1753 case '0':
1754 case '1':
1755 case '.':
1756 s += 4;
1757 break;
1758 case 'n':
1759 printf (" int n = (iword >>8) & 0xf;\n");
1760 needn = 1;
1761 s += 4;
1762 break;
1763 case 'm':
1764 printf (" int m = (iword >>4) & 0xf;\n");
1765 needm = 1;
1766 s += 4;
1767
1768 break;
1769
1770 case 'i':
1771 printf (" int i = (iword & 0x");
1772
1773 switch (s[1])
1774 {
1775 case '4':
1776 printf ("f");
1777 break;
1778 case '8':
1779 printf ("ff");
1780 break;
1781 case '1':
1782 sextbit = 12;
1783
1784 printf ("fff");
1785 break;
1786 }
1787 printf (")");
1788
1789 switch (s[3])
1790 {
1791 case '1':
1792 break;
1793 case '2':
1794 printf ("<<1");
1795 break;
1796 case '4':
1797 printf ("<<2");
1798 break;
1799 }
1800 printf (";\n");
1801 s += 4;
1802 }
1803 }
1804 if (sextbit > 0)
1805 {
1806 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1807 sextbit - 1, sextbit - 1);
1808 }
1809
1810 if (needm && needn)
1811 printf (" TB(m,n);\n");
1812 else if (needm)
1813 printf (" TL(m);\n");
1814 else if (needn)
1815 printf (" TL(n);\n");
1816
1817 {
1818 /* Do the refs */
1819 char *r;
1820 for (r = p->refs; *r; r++)
1821 {
1822 if (*r == '0') printf(" CREF(0);\n");
1823 if (*r == 'n') printf(" CREF(n);\n");
1824 if (*r == 'm') printf(" CREF(m);\n");
1825 }
1826 }
1827
1828 printf (" {\n");
1829 for (j = 0; j < MAX_NR_STUFF; j++)
1830 {
1831 if (p->stuff[j])
1832 {
1833 printf (" %s\n", p->stuff[j]);
1834 }
1835 }
1836 printf (" }\n");
1837
1838 {
1839 /* Do the defs */
1840 char *r;
1841 for (r = p->defs; *r; r++)
1842 {
1843 if (*r == '0') printf(" CDEF(0);\n");
1844 if (*r == 'n') printf(" CDEF(n);\n");
1845 if (*r == 'm') printf(" CDEF(m);\n");
1846 }
1847 }
1848
1849 printf (" break;\n");
1850 printf (" }\n");
1851 }
1852 printf (" default:\n");
1853 printf (" {\n");
1854 printf (" saved_state.asregs.exception = SIGILL;\n");
1855 printf (" }\n");
1856 printf (" }\n");
1857 printf ("}\n");
1858 }
1859
1860
1861 static void
1862 gendefines ()
1863 {
1864 op *p;
1865 filltable();
1866 for (p = tab; p->name; p++)
1867 {
1868 char *s = p->name;
1869 printf ("#define OPC_");
1870 while (*s) {
1871 if (isupper(*s))
1872 *s = tolower(*s);
1873 if (isalpha(*s)) printf("%c", *s);
1874 if (*s == ' ') printf("_");
1875 if (*s == '@') printf("ind_");
1876 if (*s == ',') printf("_");
1877 s++;
1878 }
1879 printf(" %d\n",p->index);
1880 }
1881 }
1882
1883 int
1884 main (ac, av)
1885 int ac;
1886 char **av;
1887 {
1888 /* verify the table before anything else */
1889 {
1890 op *p;
1891 for (p = tab; p->name; p++)
1892 {
1893 /* check that the code field contains 16 bits */
1894 if (strlen (p->code) != 16)
1895 {
1896 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1897 p->code, strlen (p->code), p->name);
1898 abort ();
1899 }
1900 }
1901 }
1902
1903 /* now generate the requested data */
1904 if (ac > 1)
1905 {
1906 if (strcmp (av[1], "-t") == 0)
1907 {
1908 gengastab ();
1909 }
1910 else if (strcmp (av[1], "-d") == 0)
1911 {
1912 gendefines ();
1913 }
1914 else if (strcmp (av[1], "-s") == 0)
1915 {
1916 filltable ();
1917 dumptable ();
1918
1919 }
1920 else if (strcmp (av[1], "-x") == 0)
1921 {
1922 filltable ();
1923 gensim ();
1924 }
1925 }
1926 else
1927 {
1928 genopc ();
1929 }
1930 return 0;
1931 }