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