2003-06-27 Michael Snyder <msnyder@redhat.com>
[deliverable/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 used to generate the opcode tables
29
30 */
31
32 #include <stdio.h>
33
34 #define MAX_NR_STUFF 42
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 } op;
45
46
47 op tab[] =
48 {
49
50 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
51 "R[n] += SEXT(i);",
52 "if (i == 0) {",
53 " UNDEF(n); /* see #ifdef PARANOID */",
54 " break;",
55 "}",
56 },
57 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
58 "R[n] += R[m];",
59 },
60
61 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
62 "ult = R[n] + T;",
63 "SET_SR_T (ult < R[n]);",
64 "R[n] = ult + R[m];",
65 "SET_SR_T (T || (R[n] < ult));",
66 },
67
68 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
69 "ult = R[n] + R[m];",
70 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
71 "R[n] = ult;",
72 },
73
74 { "0", "", "and #<imm>,R0", "11001001i8*1....",
75 "R0 &= i;",
76 },
77 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
78 "R[n] &= R[m];",
79 },
80 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
81 "MA (1);",
82 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
83 },
84
85 { "", "", "bf <bdisp8>", "10001011i8p1....",
86 "if (!T) {",
87 " SET_NIP (PC + 4 + (SEXT(i) * 2));",
88 " cycles += 2;",
89 "}",
90 },
91
92 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
93 "if (!T) {",
94 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
95 " cycles += 2;",
96 " Delay_Slot (PC + 2);",
97 "}",
98 },
99
100 { "", "", "bra <bdisp12>", "1010i12.........",
101 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
102 "cycles += 2;",
103 "Delay_Slot (PC + 2);",
104 },
105
106 { "", "n", "braf <REG_N>", "0000nnnn00100011",
107 "SET_NIP (PC + 4 + R[n]);",
108 "cycles += 2;",
109 "Delay_Slot (PC + 2);",
110 },
111
112 { "", "", "bsr <bdisp12>", "1011i12.........",
113 "PR = PH2T (PC + 4);",
114 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
115 "cycles += 2;",
116 "Delay_Slot (PC + 2);",
117 },
118
119 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
120 "PR = PH2T (PC) + 4;",
121 "SET_NIP (PC + 4 + R[n]);",
122 "cycles += 2;",
123 "Delay_Slot (PC + 2);",
124 },
125
126 { "", "", "bt <bdisp8>", "10001001i8p1....",
127 "if (T) {",
128 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
129 " cycles += 2;",
130 "}",
131 },
132
133 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
134 "if (T) {",
135 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
136 " cycles += 2;",
137 " Delay_Slot (PC + 2);",
138 "}",
139 },
140
141 { "", "", "clrmac", "0000000000101000",
142 "MACH = 0;",
143 "MACL = 0;",
144 },
145
146 { "", "", "clrs", "0000000001001000",
147 "SET_SR_S (0);",
148 },
149
150 { "", "", "clrt", "0000000000001000",
151 "SET_SR_T (0);",
152 },
153
154 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
155 "SET_SR_T (R0 == SEXT (i));",
156 },
157 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
158 "SET_SR_T (R[n] == R[m]);",
159 },
160 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
161 "SET_SR_T (R[n] >= R[m]);",
162 },
163 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
164 "SET_SR_T (R[n] > R[m]);",
165 },
166 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
167 "SET_SR_T (UR[n] > UR[m]);",
168 },
169 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
170 "SET_SR_T (UR[n] >= UR[m]);",
171 },
172 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
173 "SET_SR_T (R[n] > 0);",
174 },
175 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
176 "SET_SR_T (R[n] >= 0);",
177 },
178 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
179 "ult = R[n] ^ R[m];",
180 "SET_SR_T (((ult & 0xff000000) == 0)",
181 " | ((ult & 0xff0000) == 0)",
182 " | ((ult & 0xff00) == 0)",
183 " | ((ult & 0xff) == 0));",
184 },
185
186 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
187 "SET_SR_Q ((R[n] & sbit) != 0);",
188 "SET_SR_M ((R[m] & sbit) != 0);",
189 "SET_SR_T (M != Q);",
190 },
191
192 { "", "", "div0u", "0000000000011001",
193 "SET_SR_M (0);",
194 "SET_SR_Q (0);",
195 "SET_SR_T (0);",
196 },
197
198 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
199 "div1 (R, m, n/*, T*/);",
200 },
201
202 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
203 "dmul (1/*signed*/, R[n], R[m]);",
204 },
205
206 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
207 "dmul (0/*unsigned*/, R[n], R[m]);",
208 },
209
210 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
211 "R[n]--;",
212 "SET_SR_T (R[n] == 0);",
213 },
214
215 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
216 "R[n] = SEXT (R[m]);",
217 },
218 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
219 "R[n] = SEXTW (R[m]);",
220 },
221
222 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
223 "R[n] = (R[m] & 0xff);",
224 },
225 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
226 "R[n] = (R[m] & 0xffff);",
227 },
228
229 /* sh2e */
230 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
231 "FP_UNARY (n, fabs);",
232 "/* FIXME: FR(n) &= 0x7fffffff; */",
233 },
234
235 /* sh2e */
236 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
237 "FP_OP (n, +, m);",
238 },
239
240 /* sh2e */
241 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
242 "FP_CMP (n, ==, m);",
243 },
244 /* sh2e */
245 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
246 "FP_CMP (n, >, m);",
247 },
248
249 /* sh4 */
250 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
251 "if (! FPSCR_PR || n & 1)",
252 " RAISE_EXCEPTION (SIGILL);",
253 "else",
254 "{",
255 " union",
256 " {",
257 " int i;",
258 " float f;",
259 " } u;",
260 " u.f = DR(n);",
261 " FPUL = u.i;",
262 "}",
263 },
264
265 /* sh4 */
266 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
267 "if (! FPSCR_PR || n & 1)",
268 " RAISE_EXCEPTION (SIGILL);",
269 "else",
270 "{",
271 " union",
272 " {",
273 " int i;",
274 " float f;",
275 " } u;",
276 " u.i = FPUL;",
277 " SET_DR(n, u.f);",
278 "}",
279 },
280
281 /* sh2e */
282 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
283 "FP_OP (n, /, m);",
284 "/* FIXME: check for DP and (n & 1) == 0? */",
285 },
286
287 /* sh4 */
288 { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
289 "/* FIXME: not implemented */",
290 "RAISE_EXCEPTION (SIGILL);",
291 "/* FIXME: check for DP and (n & 1) == 0? */",
292 },
293
294 /* sh2e */
295 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
296 "SET_FR (n, (float)0.0);",
297 "/* FIXME: check for DP and (n & 1) == 0? */",
298 },
299
300 /* sh2e */
301 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
302 "SET_FR (n, (float)1.0);",
303 "/* FIXME: check for DP and (n & 1) == 0? */",
304 },
305
306 /* sh2e */
307 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
308 " union",
309 " {",
310 " int i;",
311 " float f;",
312 " } u;",
313 " u.f = FR(n);",
314 " FPUL = u.i;",
315 },
316
317 /* sh2e */
318 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
319 /* sh4 */
320 "if (FPSCR_PR)",
321 " SET_DR (n, (double)FPUL);",
322 "else",
323 "{",
324 " SET_FR (n, (float)FPUL);",
325 "}",
326 },
327
328 /* sh2e */
329 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
330 "SET_FR (n, FR(m) * FR(0) + FR(n));",
331 "/* FIXME: check for DP and (n & 1) == 0? */",
332 },
333
334 /* sh2e */
335 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
336 /* sh4 */
337 "if (FPSCR_SZ) {",
338 " int ni = XD_TO_XF (n);",
339 " int mi = XD_TO_XF (m);",
340 " SET_XF (ni + 0, XF (mi + 0));",
341 " SET_XF (ni + 1, XF (mi + 1));",
342 "}",
343 "else",
344 "{",
345 " SET_FR (n, FR (m));",
346 "}",
347 },
348 /* sh2e */
349 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
350 /* sh4 */
351 "if (FPSCR_SZ) {",
352 " MA (2);",
353 " WDAT (R[n], m);",
354 "}",
355 "else",
356 "{",
357 " MA (1);",
358 " WLAT (R[n], FI(m));",
359 "}",
360 },
361 /* sh2e */
362 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
363 /* sh4 */
364 "if (FPSCR_SZ) {",
365 " MA (2);",
366 " RDAT (R[m], n);",
367 "}",
368 "else",
369 "{",
370 " MA (1);",
371 " SET_FI(n, RLAT(R[m]));",
372 "}",
373 },
374 /* sh2e */
375 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
376 /* sh4 */
377 "if (FPSCR_SZ) {",
378 " MA (2);",
379 " RDAT (R[m], n);",
380 " R[m] += 8;",
381 "}",
382 "else",
383 "{",
384 " MA (1);",
385 " SET_FI (n, RLAT (R[m]));",
386 " R[m] += 4;",
387 "}",
388 },
389 /* sh2e */
390 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
391 /* sh4 */
392 "if (FPSCR_SZ) {",
393 " MA (2);",
394 " R[n] -= 8;",
395 " WDAT (R[n], m);",
396 "}",
397 "else",
398 "{",
399 " MA (1);",
400 " R[n] -= 4;",
401 " WLAT (R[n], FI(m));",
402 "}",
403 },
404 /* sh2e */
405 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
406 /* sh4 */
407 "if (FPSCR_SZ) {",
408 " MA (2);",
409 " RDAT (R[0]+R[m], n);",
410 "}",
411 "else",
412 "{",
413 " MA (1);",
414 " SET_FI(n, RLAT(R[0] + R[m]));",
415 "}",
416 },
417 /* sh2e */
418 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
419 /* sh4 */
420 "if (FPSCR_SZ) {",
421 " MA (2);",
422 " WDAT (R[0]+R[n], m);",
423 "}",
424 "else",
425 "{",
426 " MA (1);",
427 " WLAT((R[0]+R[n]), FI(m));",
428 "}",
429 },
430
431 /* sh4: See fmov instructions above for move to/from extended fp registers */
432
433 /* sh2e */
434 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
435 "FP_OP(n, *, m);",
436 },
437
438 /* sh2e */
439 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
440 "FP_UNARY(n, -);",
441 },
442
443 /* sh4 */
444 { "", "", "frchg", "1111101111111101",
445 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
446 },
447
448 /* sh4 */
449 { "", "", "fschg", "1111001111111101",
450 "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
451 },
452
453 /* sh3e */
454 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
455 "FP_UNARY(n, sqrt);",
456 },
457
458 /* sh2e */
459 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
460 "FP_OP(n, -, m);",
461 },
462
463 /* sh2e */
464 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
465 /* sh4 */
466 "if (FPSCR_PR) {",
467 " if (DR(n) != DR(n)) /* NaN */",
468 " FPUL = 0x80000000;",
469 " else",
470 " FPUL = (int)DR(n);",
471 "}",
472 "else",
473 "if (FR(n) != FR(n)) /* NaN */",
474 " FPUL = 0x80000000;",
475 "else",
476 " FPUL = (int)FR(n);",
477 },
478
479 /* sh2e */
480 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
481 " union",
482 " {",
483 " int i;",
484 " float f;",
485 " } u;",
486 " u.i = FPUL;",
487 " SET_FR (n, u.f);",
488 },
489
490 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
491 "SET_NIP (PT2H (R[n]));",
492 "cycles += 2;",
493 "Delay_Slot (PC + 2);",
494 },
495
496 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
497 "PR = PH2T (PC + 4);",
498 "if (~doprofile)",
499 " gotcall (PR, R[n]);",
500 "SET_NIP (PT2H (R[n]));",
501 "cycles += 2;",
502 "Delay_Slot (PC + 2);",
503 },
504
505 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
506 "CREG (m) = R[n];",
507 "/* FIXME: user mode */",
508 },
509 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
510 "SET_SR (R[n]);",
511 "/* FIXME: user mode */",
512 },
513 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
514 "SET_MOD (R[n]);",
515 },
516 #if 0
517 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
518 "DBR = R[n];",
519 "/* FIXME: user mode */",
520 },
521 #endif
522 { "", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
523 "MA (1);",
524 "CREG (m) = RLAT (R[n]);",
525 "R[n] += 4;",
526 "/* FIXME: user mode */",
527 },
528 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
529 "MA (1);",
530 "SET_SR (RLAT (R[n]));",
531 "R[n] += 4;",
532 "/* FIXME: user mode */",
533 },
534 { "", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
535 "MA (1);",
536 "SET_MOD (RLAT (R[n]));",
537 "R[n] += 4;",
538 },
539 #if 0
540 { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
541 "MA (1);",
542 "DBR = RLAT (R[n]);",
543 "R[n] += 4;",
544 "/* FIXME: user mode */",
545 },
546 #endif
547
548 /* sh-dsp */
549 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
550 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
551 },
552 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
553 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
554 },
555
556 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
557 "SREG (m) = R[n];",
558 },
559 { "", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
560 "MA (1);",
561 "SREG (m) = RLAT(R[n]);",
562 "R[n] += 4;",
563 },
564 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
565 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
566 "SET_FPSCR(R[n]);",
567 },
568 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
569 { "", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
570 "MA (1);",
571 "SET_FPSCR (RLAT(R[n]));",
572 "R[n] += 4;",
573 },
574
575 { "", "", "ldtlb", "0000000000111000",
576 "/* FIXME: XXX*/ abort();",
577 },
578
579 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
580 "trap (255, R0, PC, memory, maskl, maskw, endianw);",
581 "/* FIXME: mac.l support */",
582 },
583
584 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
585 "macw(R0,memory,n,m,endianw);",
586 },
587
588 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
589 "R[n] = SEXT(i);",
590 },
591 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
592 "R[n] = R[m];",
593 },
594
595 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
596 "MA (1);",
597 "R0 = RSBAT (i + GBR);",
598 "L (0);",
599 },
600 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
601 "MA (1);",
602 "R0 = RSBAT (i + R[m]);",
603 "L (0);",
604 },
605 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
606 "MA (1);",
607 "R[n] = RSBAT (R0 + R[m]);",
608 "L (n);",
609 },
610 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
611 "MA (1);",
612 "R[n] = RSBAT (R[m]);",
613 "R[m] += 1;",
614 "L (n);",
615 },
616 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
617 "MA (1);",
618 "WBAT (R[n], R[m]);",
619 },
620 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
621 "MA (1);",
622 "WBAT (i + GBR, R0);",
623 },
624 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
625 "MA (1);",
626 "WBAT (i + R[m], R0);",
627 },
628 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
629 "MA (1);",
630 "WBAT (R[n] + R0, R[m]);",
631 },
632 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
633 "MA (1);",
634 "R[n] -= 1;",
635 "WBAT (R[n], R[m]);",
636 },
637 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
638 "MA (1);",
639 "R[n] = RSBAT (R[m]);",
640 "L (n);",
641 },
642
643 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
644 "MA (1);",
645 "R0 = RLAT (i + GBR);",
646 "L (0);",
647 },
648 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
649 "MA (1);",
650 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
651 "L (n);",
652 },
653 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
654 "MA (1);",
655 "R[n] = RLAT (i + R[m]);",
656 "L (n);",
657 },
658 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
659 "MA (1);",
660 "R[n] = RLAT (R0 + R[m]);",
661 "L (n);",
662 },
663 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
664 "MA (1);",
665 "R[n] = RLAT (R[m]);",
666 "R[m] += 4;",
667 "L (n);",
668 },
669 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
670 "MA (1);",
671 "R[n] = RLAT (R[m]);",
672 "L (n);",
673 },
674 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
675 "MA (1);",
676 "WLAT (i + GBR, R0);",
677 },
678 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
679 "MA (1);",
680 "WLAT (i + R[n], R[m]);",
681 },
682 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
683 "MA (1);",
684 "WLAT (R0 + R[n], R[m]);",
685 },
686 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
687 "MA (1) ;",
688 "R[n] -= 4;",
689 "WLAT (R[n], R[m]);",
690 },
691 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
692 "MA (1);",
693 "WLAT (R[n], R[m]);",
694 },
695
696 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
697 "MA (1);",
698 "R0 = RSWAT (i + GBR);",
699 "L (0);",
700 },
701 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
702 "MA (1);",
703 "R[n] = RSWAT (PH2T (PC + 4 + i));",
704 "L (n);",
705 },
706 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
707 "MA (1);",
708 "R0 = RSWAT (i + R[m]);",
709 "L (0);",
710 },
711 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
712 "MA (1);",
713 "R[n] = RSWAT (R0 + R[m]);",
714 "L (n);",
715 },
716 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
717 "MA (1);",
718 "R[n] = RSWAT (R[m]);",
719 "R[m] += 2;",
720 "L (n);",
721 },
722 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
723 "MA (1);",
724 "R[n] = RSWAT (R[m]);",
725 "L (n);",
726 },
727 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
728 "MA (1);",
729 "WWAT (i + GBR, R0);",
730 },
731 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
732 "MA (1);",
733 "WWAT (i + R[m], R0);",
734 },
735 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
736 "MA (1);",
737 "WWAT (R0 + R[n], R[m]);",
738 },
739 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
740 "MA (1);",
741 "R[n] -= 2;",
742 "WWAT (R[n], R[m]);",
743 },
744 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
745 "MA (1);",
746 "WWAT (R[n], R[m]);",
747 },
748
749 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
750 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
751 },
752
753 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
754 "/* We don't simulate cache, so this insn is identical to mov. */",
755 "MA (1);",
756 "WLAT (R[n], R[0]);",
757 },
758
759 { "n", "", "movt <REG_N>", "0000nnnn00101001",
760 "R[n] = T;",
761 },
762
763 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
764 "MACL = ((int)R[n]) * ((int)R[m]);",
765 },
766 #if 0
767 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
768 "MACL = R[n] * R[m];",
769 },
770 #endif
771
772 /* muls.w - see muls */
773 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
774 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
775 },
776
777 /* mulu.w - see mulu */
778 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
779 "MACL = (((unsigned int)(unsigned short)R[n])",
780 " * ((unsigned int)(unsigned short)R[m]));",
781 },
782
783 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
784 "R[n] = - R[m];",
785 },
786
787 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
788 "ult = -T;",
789 "SET_SR_T (ult > 0);",
790 "R[n] = ult - R[m];",
791 "SET_SR_T (T || (R[n] > ult));",
792 },
793
794 { "", "", "nop", "0000000000001001",
795 "/* nop */",
796 },
797
798 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
799 "R[n] = ~R[m];",
800 },
801
802 { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
803 "/* FIXME: Not implemented */",
804 "RAISE_EXCEPTION (SIGILL);",
805 },
806
807 { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
808 "/* FIXME: Not implemented */",
809 "RAISE_EXCEPTION (SIGILL);",
810 },
811
812 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
813 "RSBAT (R[n]); /* Take exceptions like byte load. */",
814 "/* FIXME: Cache not implemented */",
815 },
816
817 { "0", "", "or #<imm>,R0", "11001011i8*1....",
818 "R0 |= i;",
819 },
820 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
821 "R[n] |= R[m];",
822 },
823 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
824 "MA (1);",
825 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
826 },
827
828 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
829 "/* Except for the effect on the cache - which is not simulated -",
830 " this is like a nop. */",
831 },
832
833 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
834 "ult = R[n] < 0;",
835 "R[n] = (R[n] << 1) | T;",
836 "SET_SR_T (ult);",
837 },
838
839 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
840 "ult = R[n] & 1;",
841 "R[n] = (UR[n] >> 1) | (T << 31);",
842 "SET_SR_T (ult);",
843 },
844
845 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
846 "SET_SR_T (R[n] < 0);",
847 "R[n] <<= 1;",
848 "R[n] |= T;",
849 },
850
851 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
852 "SET_SR_T (R[n] & 1);",
853 "R[n] = UR[n] >> 1;",
854 "R[n] |= (T << 31);",
855 },
856
857 { "", "", "rte", "0000000000101011",
858 #if 0
859 /* SH-[12] */
860 "int tmp = PC;",
861 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
862 "R[15] += 4;",
863 "SET_SR (RLAT (R[15]) & 0x3f3);",
864 "R[15] += 4;",
865 "Delay_Slot (PC + 2);",
866 #else
867 "SET_SR (SSR);",
868 "SET_NIP (PT2H (SPC));",
869 "cycles += 2;",
870 "Delay_Slot (PC + 2);",
871 #endif
872 },
873
874 { "", "", "rts", "0000000000001011",
875 "SET_NIP (PT2H (PR));",
876 "cycles += 2;",
877 "Delay_Slot (PC + 2);",
878 },
879
880 /* sh-dsp */
881 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
882 "SET_RC (R[n]);",
883 },
884 { "", "n", "setrc #<imm>", "10000010i8*1....",
885 /* It would be more realistic to let loop_start point to some static
886 memory that contains an illegal opcode and then give a bus error when
887 the loop is eventually encountered, but it seems not only simpler,
888 but also more debugging-friendly to just catch the failure here. */
889 "if (BUSERROR (RS | RE, maskw))",
890 " RAISE_EXCEPTION (SIGILL);",
891 "else {",
892 " SET_RC (i);",
893 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
894 " CHECK_INSN_PTR (insn_ptr);",
895 "}",
896 },
897
898 { "", "", "sets", "0000000001011000",
899 "SET_SR_S (1);",
900 },
901
902 { "", "", "sett", "0000000000011000",
903 "SET_SR_T (1);",
904 },
905
906 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
907 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
908 },
909
910 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
911 "SET_SR_T (R[n] < 0);",
912 "R[n] <<= 1;",
913 },
914
915 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
916 "SET_SR_T (R[n] & 1);",
917 "R[n] = R[n] >> 1;",
918 },
919
920 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
921 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
922 },
923
924 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
925 "SET_SR_T (R[n] < 0);",
926 "R[n] <<= 1;",
927 },
928
929 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
930 "R[n] <<= 2;",
931 },
932 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
933 "R[n] <<= 8;",
934 },
935 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
936 "R[n] <<= 16;",
937 },
938
939 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
940 "SET_SR_T (R[n] & 1);",
941 "R[n] = UR[n] >> 1;",
942 },
943
944 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
945 "R[n] = UR[n] >> 2;",
946 },
947 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
948 "R[n] = UR[n] >> 8;",
949 },
950 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
951 "R[n] = UR[n] >> 16;",
952 },
953
954 { "", "", "sleep", "0000000000011011",
955 "nip += trap (0xc3, R0, PC, memory, maskl, maskw, endianw);",
956 },
957
958 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
959 "R[n] = CREG (m);",
960 },
961
962 #if 0
963 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
964 "R[n] = SGR;",
965 },
966 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
967 "R[n] = DBR;",
968 },
969 #endif
970 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
971 "MA (1);",
972 "R[n] -= 4;",
973 "WLAT (R[n], CREG (m));",
974 },
975 #if 0
976 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
977 "MA (1);",
978 "R[n] -= 4;",
979 "WLAT (R[n], SGR);",
980 },
981 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
982 "MA (1);",
983 "R[n] -= 4;",
984 "WLAT (R[n], DBR);",
985 },
986 #endif
987
988 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
989 "R[n] = SREG (m);",
990 },
991 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
992 "MA (1);",
993 "R[n] -= 4;",
994 "WLAT (R[n], SREG (m));",
995 },
996
997 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
998 "R[n] -= R[m];",
999 },
1000
1001 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1002 "ult = R[n] - T;",
1003 "SET_SR_T (ult > R[n]);",
1004 "R[n] = ult - R[m];",
1005 "SET_SR_T (T || (R[n] > ult));",
1006 },
1007
1008 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1009 "ult = R[n] - R[m];",
1010 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1011 "R[n] = ult;",
1012 },
1013
1014 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1015 "R[n] = ((R[m] & 0xffff0000)",
1016 " | ((R[m] << 8) & 0xff00)",
1017 " | ((R[m] >> 8) & 0x00ff));",
1018 },
1019 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1020 "R[n] = (((R[m] << 16) & 0xffff0000)",
1021 " | ((R[m] >> 16) & 0x00ffff));",
1022 },
1023
1024 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1025 "MA (1);",
1026 "ult = RBAT(R[n]);",
1027 "SET_SR_T (ult == 0);",
1028 "WBAT(R[n],ult|0x80);",
1029 },
1030
1031 { "0", "", "trapa #<imm>", "11000011i8*1....",
1032 "long imm = 0xff & i;",
1033 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1034 " nip += trap (i, R, PC, memory, maskl, maskw,endianw);",
1035 #if 0
1036 "else {",
1037 /* SH-[12] */
1038 " R[15]-=4;",
1039 " WLAT (R[15], GET_SR());",
1040 " R[15]-=4;",
1041 " WLAT (R[15], PH2T (PC + 2));",
1042 #else
1043 "else if (!SR_BL) {",
1044 " SSR = GET_SR();",
1045 " SPC = PH2T (PC + 2);",
1046 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1047 " /* FIXME: EXPEVT = 0x00000160; */",
1048 #endif
1049 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1050 "}",
1051 },
1052
1053 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1054 "SET_SR_T ((R[n] & R[m]) == 0);",
1055 },
1056 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1057 "SET_SR_T ((R0 & i) == 0);",
1058 },
1059 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1060 "MA (1);",
1061 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1062 },
1063
1064 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1065 "R0 ^= i;",
1066 },
1067 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1068 "R[n] ^= R[m];",
1069 },
1070 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1071 "MA (1);",
1072 "ult = RBAT (GBR+R0);",
1073 "ult ^= i;",
1074 "WBAT (GBR + R0, ult);",
1075 },
1076
1077 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1078 "R[n] = (((R[n] >> 16) & 0xffff)",
1079 " | ((R[m] << 16) & 0xffff0000));",
1080 },
1081
1082 #if 0
1083 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1084 "divl(0,R[n],R[m]);",
1085 },
1086 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1087 "divl(0,R[n],R[m]);",
1088 },
1089 #endif
1090
1091 {0, 0}};
1092
1093 op movsxy_tab[] =
1094 {
1095 /* If this is disabled, the simulator speeds up by about 12% on a
1096 450 MHz PIII - 9% with ACE_FAST.
1097 Maybe we should have separate simulator loops? */
1098 #if 1
1099 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1100 "MA (1);",
1101 "R[n] -= 2;",
1102 "DSP_R (m) = RSWAT (R[n]) << 16;",
1103 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1104 },
1105 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1106 "MA (1);",
1107 "DSP_R (m) = RSWAT (R[n]) << 16;",
1108 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1109 },
1110 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1111 "MA (1);",
1112 "DSP_R (m) = RSWAT (R[n]) << 16;",
1113 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1114 "R[n] += 2;",
1115 },
1116 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1117 "MA (1);",
1118 "DSP_R (m) = RSWAT (R[n]) << 16;",
1119 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1120 "R[n] += R[8];",
1121 },
1122 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1123 "MA (1);",
1124 "R[n] -= 2;",
1125 "DSP_R (m) = RSWAT (R[n]);",
1126 },
1127 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1128 "MA (1);",
1129 "DSP_R (m) = RSWAT (R[n]);",
1130 },
1131 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1132 "MA (1);",
1133 "DSP_R (m) = RSWAT (R[n]);",
1134 "R[n] += 2;",
1135 },
1136 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1137 "MA (1);",
1138 "DSP_R (m) = RSWAT (R[n]);",
1139 "R[n] += R[8];",
1140 },
1141 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1142 "MA (1);",
1143 "R[n] -= 2;",
1144 "WWAT (R[n], DSP_R (m) >> 16);",
1145 },
1146 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1147 "MA (1);",
1148 "WWAT (R[n], DSP_R (m) >> 16);",
1149 },
1150 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1151 "MA (1);",
1152 "WWAT (R[n], DSP_R (m) >> 16);",
1153 "R[n] += 2;",
1154 },
1155 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1156 "MA (1);",
1157 "WWAT (R[n], DSP_R (m) >> 16);",
1158 "R[n] += R[8];",
1159 },
1160 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1161 "MA (1);",
1162 "R[n] -= 2;",
1163 "WWAT (R[n], SEXT (DSP_R (m)));",
1164 },
1165 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1166 "MA (1);",
1167 "WWAT (R[n], SEXT (DSP_R (m)));",
1168 },
1169 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1170 "MA (1);",
1171 "WWAT (R[n], SEXT (DSP_R (m)));",
1172 "R[n] += 2;",
1173 },
1174 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1175 "MA (1);",
1176 "WWAT (R[n], SEXT (DSP_R (m)));",
1177 "R[n] += R[8];",
1178 },
1179 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1180 "MA (1);",
1181 "R[n] -= 4;",
1182 "DSP_R (m) = RLAT (R[n]);",
1183 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1184 },
1185 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1186 "MA (1);",
1187 "DSP_R (m) = RLAT (R[n]);",
1188 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1189 },
1190 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1191 "MA (1);",
1192 "DSP_R (m) = RLAT (R[n]);",
1193 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1194 "R[n] += 4;",
1195 },
1196 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1197 "MA (1);",
1198 "DSP_R (m) = RLAT (R[n]);",
1199 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1200 "R[n] += R[8];",
1201 },
1202 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1203 "MA (1);",
1204 "R[n] -= 4;",
1205 "WLAT (R[n], DSP_R (m));",
1206 },
1207 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1208 "MA (1);",
1209 "WLAT (R[n], DSP_R (m));",
1210 },
1211 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1212 "MA (1);",
1213 "WLAT (R[n], DSP_R (m));",
1214 "R[n] += 4;",
1215 },
1216 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1217 "MA (1);",
1218 "WLAT (R[n], DSP_R (m));",
1219 "R[n] += R[8];",
1220 },
1221 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1222 "MA (1);",
1223 "R[n] -= 4;",
1224 "WLAT (R[n], SEXT (DSP_R (m)));",
1225 },
1226 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1227 "MA (1);",
1228 "WLAT (R[n], SEXT (DSP_R (m)));",
1229 },
1230 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1231 "MA (1);",
1232 "WLAT (R[n], SEXT (DSP_R (m)));",
1233 "R[n] += 4;",
1234 },
1235 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1236 "MA (1);",
1237 "WLAT (R[n], SEXT (DSP_R (m)));",
1238 "R[n] += R[8];",
1239 },
1240 { "", "n", "movx.w @<REG_x>,<DSP_XX>", "111100xxXX000100",
1241 "DSP_R (m) = RSWAT (R[n]) << 16;",
1242 "iword &= 0xfd53; goto top;",
1243 },
1244 { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1245 "DSP_R (m) = RSWAT (R[n]) << 16;",
1246 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1247 "iword &= 0xfd53; goto top;",
1248 },
1249 { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1250 "DSP_R (m) = RSWAT (R[n]) << 16;",
1251 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1252 "iword &= 0xfd53; goto top;",
1253 },
1254 { "", "n", "movx.w <DSP_Aa>,@<REG_x>", "111100xxaa100100",
1255 "WWAT (R[n], DSP_R (m) >> 16);",
1256 "iword &= 0xfd53; goto top;",
1257 },
1258 { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1259 "WWAT (R[n], DSP_R (m) >> 16);",
1260 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1261 "iword &= 0xfd53; goto top;",
1262 },
1263 { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101100",
1264 "WWAT (R[n], DSP_R (m) >> 16);",
1265 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1266 "iword &= 0xfd53; goto top;",
1267 },
1268 { "", "n", "movy.w @<REG_y>,<DSP_YY>", "111100yyYY000001",
1269 "DSP_R (m) = RSWAT (R[n]) << 16;",
1270 },
1271 { "n", "n", "movy.w @<REG_y>+,<DSP_YY>", "111100yyYY000010",
1272 "DSP_R (m) = RSWAT (R[n]) << 16;",
1273 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1274 },
1275 { "n", "n9","movy.w @<REG_y>+REG_9,<DSP_YY>", "111100yyYY000010",
1276 "DSP_R (m) = RSWAT (R[n]) << 16;",
1277 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1278 },
1279 { "", "n", "movy.w <DSP_Aa>,@<REG_y>", "111100yyAA010001",
1280 "WWAT (R[n], DSP_R (m) >> 16);",
1281 },
1282 { "n", "n", "movy.w <DSP_Aa>,@<REG_y>+", "111100yyAA010010",
1283 "WWAT (R[n], DSP_R (m) >> 16);",
1284 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1285 },
1286 { "n", "n9", "movy.w <DSP_Aa>,@<REG_y>+REG_9", "111100yyAA010010",
1287 "WWAT (R[n], DSP_R (m) >> 16);",
1288 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1289 },
1290 { "", "", "nopx nopy", "1111000000000000",
1291 "/* nop */",
1292 },
1293 { "", "", "ppi", "1111100000000000",
1294 "ppi_insn (RIAT (nip));",
1295 "nip += 2;",
1296 "iword &= 0xf7ff; goto top;",
1297 },
1298 #endif
1299 {0, 0}};
1300
1301 op ppi_tab[] =
1302 {
1303 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1304 "int Sz = DSP_R (z) & 0xffff0000;",
1305 "",
1306 "if (i < 16)",
1307 " res = Sz << i;",
1308 "else if (i >= 128 - 16)",
1309 " res = Sz >> 128 - i;",
1310 "else",
1311 " {",
1312 " RAISE_EXCEPTION (SIGILL);",
1313 " return;",
1314 " }",
1315 "res &= 0xffff0000;",
1316 "res_grd = 0;",
1317 "goto logical;",
1318 },
1319 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1320 "int Sz = DSP_R (z);",
1321 "int Sz_grd = GET_DSP_GRD (z);",
1322 "",
1323 "if (i < 32)",
1324 " {",
1325 " if (i == 32)",
1326 " {",
1327 " res = 0;",
1328 " res_grd = Sz;",
1329 " }",
1330 " else",
1331 " {",
1332 " res = Sz << i;",
1333 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1334 " }",
1335 " res_grd = SEXT (res_grd);",
1336 " carry = res_grd & 1;",
1337 " }",
1338 "else if (i >= 96)",
1339 " {",
1340 " i = 128 - i;",
1341 " if (i == 32)",
1342 " {",
1343 " res_grd = SIGN32 (Sz_grd);",
1344 " res = Sz_grd;",
1345 " }",
1346 " else",
1347 " {",
1348 " res = Sz >> i | Sz_grd << 32 - i;",
1349 " res_grd = Sz_grd >> i;",
1350 " }",
1351 " carry = Sz >> (i - 1) & 1;",
1352 " }",
1353 "else",
1354 " {",
1355 " RAISE_EXCEPTION (SIGILL);",
1356 " return;",
1357 " }",
1358 "COMPUTE_OVERFLOW;",
1359 "greater_equal = 0;",
1360 },
1361 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1362 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1363 "if (res == 0x80000000)",
1364 " res = 0x7fffffff;",
1365 "DSP_R (g) = res;",
1366 "DSP_GRD (g) = SIGN32 (res);",
1367 "return;",
1368 },
1369 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1370 "int Sx = DSP_R (x);",
1371 "int Sx_grd = GET_DSP_GRD (x);",
1372 "int Sy = DSP_R (y);",
1373 "int Sy_grd = SIGN32 (Sy);",
1374 "",
1375 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1376 "if (res == 0x80000000)",
1377 " res = 0x7fffffff;",
1378 "DSP_R (g) = res;",
1379 "DSP_GRD (g) = SIGN32 (res);",
1380 "",
1381 "z = u;",
1382 "res = Sx - Sy;",
1383 "carry = (unsigned) res > (unsigned) Sx;",
1384 "res_grd = Sx_grd - Sy_grd - carry;",
1385 "COMPUTE_OVERFLOW;",
1386 "ADD_SUB_GE;",
1387 },
1388 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1389 "int Sx = DSP_R (x);",
1390 "int Sx_grd = GET_DSP_GRD (x);",
1391 "int Sy = DSP_R (y);",
1392 "int Sy_grd = SIGN32 (Sy);",
1393 "",
1394 "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1395 "if (res == 0x80000000)",
1396 " res = 0x7fffffff;",
1397 "DSP_R (g) = res;",
1398 "DSP_GRD (g) = SIGN32 (res);",
1399 "",
1400 "z = u;",
1401 "res = Sx + Sy;",
1402 "carry = (unsigned) res < (unsigned) Sx;",
1403 "res_grd = Sx_grd + Sy_grd + carry;",
1404 "COMPUTE_OVERFLOW;",
1405 },
1406 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1407 "int Sx = DSP_R (x);",
1408 "int Sx_grd = GET_DSP_GRD (x);",
1409 "int Sy = DSP_R (y);",
1410 "int Sy_grd = SIGN32 (Sy);",
1411 "",
1412 "res = Sx - Sy - (DSR & 1);",
1413 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1414 "res_grd = Sx_grd + Sy_grd + carry;",
1415 "COMPUTE_OVERFLOW;",
1416 "ADD_SUB_GE;",
1417 "DSR &= ~0xf1;\n",
1418 "if (res || res_grd)\n",
1419 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1420 "else\n",
1421 " DSR |= DSR_MASK_Z | overflow;\n",
1422 "DSR |= carry;\n",
1423 "goto assign_z;\n",
1424 },
1425 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1426 "int Sx = DSP_R (x);",
1427 "int Sx_grd = GET_DSP_GRD (x);",
1428 "int Sy = DSP_R (y);",
1429 "int Sy_grd = SIGN32 (Sy);",
1430 "",
1431 "res = Sx + Sy + (DSR & 1);",
1432 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1433 "res_grd = Sx_grd + Sy_grd + carry;",
1434 "COMPUTE_OVERFLOW;",
1435 "ADD_SUB_GE;",
1436 "DSR &= ~0xf1;\n",
1437 "if (res || res_grd)\n",
1438 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1439 "else\n",
1440 " DSR |= DSR_MASK_Z | overflow;\n",
1441 "DSR |= carry;\n",
1442 "goto assign_z;\n",
1443 },
1444 { "","", "pcmp Sx,Sy", "10000100xxyy....",
1445 "int Sx = DSP_R (x);",
1446 "int Sx_grd = GET_DSP_GRD (x);",
1447 "int Sy = DSP_R (y);",
1448 "int Sy_grd = SIGN32 (Sy);",
1449 "",
1450 "z = 17; /* Ignore result. */",
1451 "res = Sx - Sy;",
1452 "carry = (unsigned) res > (unsigned) Sx;",
1453 "res_grd = Sx_grd - Sy_grd - carry;",
1454 "COMPUTE_OVERFLOW;",
1455 "ADD_SUB_GE;",
1456 },
1457 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1458 },
1459 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1460 },
1461 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
1462 "res = DSP_R (x);",
1463 "res_grd = GET_DSP_GRD (x);",
1464 "if (res >= 0)",
1465 " carry = 0;",
1466 "else",
1467 " {",
1468 " res = -res;",
1469 " carry = (res != 0); /* The manual has a bug here. */",
1470 " res_grd = -res_grd - carry;",
1471 " }",
1472 "COMPUTE_OVERFLOW;",
1473 "/* ??? The re-computing of overflow after",
1474 " saturation processing is specific to pabs. */",
1475 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1476 "ADD_SUB_GE;",
1477 },
1478 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
1479 "int Sx = DSP_R (x);",
1480 "int Sx_grd = GET_DSP_GRD (x);",
1481 "",
1482 "res = Sx + 0x8000;",
1483 "carry = (unsigned) res < (unsigned) Sx;",
1484 "res_grd = Sx_grd + carry;",
1485 "COMPUTE_OVERFLOW;",
1486 "ADD_SUB_GE;",
1487 },
1488 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
1489 "res = DSP_R (y);",
1490 "res_grd = 0;",
1491 "overflow = 0;",
1492 "greater_equal = DSR_MASK_G;",
1493 "if (res >= 0)",
1494 " carry = 0;",
1495 "else",
1496 " {",
1497 " res = -res;",
1498 " carry = 1;",
1499 " if (res < 0)",
1500 " {",
1501 " if (S)",
1502 " res = 0x7fffffff;",
1503 " else",
1504 " {",
1505 " overflow = DSR_MASK_V;",
1506 " greater_equal = 0;",
1507 " }",
1508 " }",
1509 " }",
1510 },
1511 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
1512 "int Sy = DSP_R (y);",
1513 "int Sy_grd = SIGN32 (Sy);",
1514 "",
1515 "res = Sy + 0x8000;",
1516 "carry = (unsigned) res < (unsigned) Sy;",
1517 "res_grd = Sy_grd + carry;",
1518 "COMPUTE_OVERFLOW;",
1519 "ADD_SUB_GE;",
1520 },
1521 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
1522 "int Sx = DSP_R (x) & 0xffff0000;",
1523 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1524 "",
1525 "if (Sy < 16)",
1526 " res = Sx << Sy;",
1527 "else if (Sy >= 128 - 16)",
1528 " res = Sx >> 128 - Sy;",
1529 "else",
1530 " {",
1531 " RAISE_EXCEPTION (SIGILL);",
1532 " return;",
1533 " }",
1534 "goto cond_logical;",
1535 },
1536 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
1537 "int Sx = DSP_R (x);",
1538 "int Sx_grd = GET_DSP_GRD (x);",
1539 "int Sy = DSP_R (y) >> 16 & 0x7f;",
1540 "",
1541 "if (Sy < 32)",
1542 " {",
1543 " if (Sy == 32)",
1544 " {",
1545 " res = 0;",
1546 " res_grd = Sx;",
1547 " }",
1548 " else",
1549 " {",
1550 " res = Sx << Sy;",
1551 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1552 " }",
1553 " res_grd = SEXT (res_grd);",
1554 " carry = res_grd & 1;",
1555 " }",
1556 "else if (Sy >= 96)",
1557 " {",
1558 " Sy = 128 - Sy;",
1559 " if (Sy == 32)",
1560 " {",
1561 " res_grd = SIGN32 (Sx_grd);",
1562 " res = Sx_grd;",
1563 " }",
1564 " else",
1565 " {",
1566 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
1567 " res_grd = Sx_grd >> Sy;",
1568 " }",
1569 " carry = Sx >> (Sy - 1) & 1;",
1570 " }",
1571 "else",
1572 " {",
1573 " RAISE_EXCEPTION (SIGILL);",
1574 " return;",
1575 " }",
1576 "COMPUTE_OVERFLOW;",
1577 "greater_equal = 0;",
1578 },
1579 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
1580 "int Sx = DSP_R (x);",
1581 "int Sx_grd = GET_DSP_GRD (x);",
1582 "int Sy = DSP_R (y);",
1583 "int Sy_grd = SIGN32 (Sy);",
1584 "",
1585 "res = Sx - Sy;",
1586 "carry = (unsigned) res > (unsigned) Sx;",
1587 "res_grd = Sx_grd - Sy_grd - carry;",
1588 "COMPUTE_OVERFLOW;",
1589 "ADD_SUB_GE;",
1590 },
1591 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
1592 "int Sx = DSP_R (x);",
1593 "int Sx_grd = GET_DSP_GRD (x);",
1594 "int Sy = DSP_R (y);",
1595 "int Sy_grd = SIGN32 (Sy);",
1596 "",
1597 "res = Sx + Sy;",
1598 "carry = (unsigned) res < (unsigned) Sx;",
1599 "res_grd = Sx_grd + Sy_grd + carry;",
1600 "COMPUTE_OVERFLOW;",
1601 "ADD_SUB_GE;",
1602 },
1603 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
1604 "res = DSP_R (x) & DSP_R (y);",
1605 "cond_logical:",
1606 "res &= 0xffff0000;",
1607 "res_grd = 0;",
1608 "if (iword & 0x200)\n",
1609 " goto assign_z;\n",
1610 "logical:",
1611 "carry = 0;",
1612 "overflow = 0;",
1613 "greater_equal = 0;",
1614 "DSR &= ~0xf1;\n",
1615 "if (res)\n",
1616 " DSR |= res >> 26 & DSR_MASK_N;\n",
1617 "else\n",
1618 " DSR |= DSR_MASK_Z;\n",
1619 "goto assign_dc;\n",
1620 },
1621 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
1622 "res = DSP_R (x) ^ DSP_R (y);",
1623 "goto cond_logical;",
1624 },
1625 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
1626 "res = DSP_R (x) | DSP_R (y);",
1627 "goto cond_logical;",
1628 },
1629 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
1630 "int Sx = DSP_R (x);",
1631 "int Sx_grd = GET_DSP_GRD (x);",
1632 "",
1633 "res = Sx - 0x10000;",
1634 "carry = res > Sx;",
1635 "res_grd = Sx_grd - carry;",
1636 "COMPUTE_OVERFLOW;",
1637 "ADD_SUB_GE;",
1638 "res &= 0xffff0000;",
1639 },
1640 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
1641 "int Sx = DSP_R (x);",
1642 "int Sx_grd = GET_DSP_GRD (x);",
1643 "",
1644 "res = Sx + 0x10000;",
1645 "carry = res < Sx;",
1646 "res_grd = Sx_grd + carry;",
1647 "COMPUTE_OVERFLOW;",
1648 "ADD_SUB_GE;",
1649 "res &= 0xffff0000;",
1650 },
1651 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
1652 "int Sy = DSP_R (y);",
1653 "int Sy_grd = SIGN32 (Sy);",
1654 "",
1655 "res = Sy - 0x10000;",
1656 "carry = res > Sy;",
1657 "res_grd = Sy_grd - carry;",
1658 "COMPUTE_OVERFLOW;",
1659 "ADD_SUB_GE;",
1660 "res &= 0xffff0000;",
1661 },
1662 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
1663 "int Sy = DSP_R (y);",
1664 "int Sy_grd = SIGN32 (Sy);",
1665 "",
1666 "res = Sy + 0x10000;",
1667 "carry = res < Sy;",
1668 "res_grd = Sy_grd + carry;",
1669 "COMPUTE_OVERFLOW;",
1670 "ADD_SUB_GE;",
1671 "res &= 0xffff0000;",
1672 },
1673 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
1674 "res = 0;",
1675 "res_grd = 0;",
1676 "carry = 0;",
1677 "overflow = 0;",
1678 "greater_equal = 1;",
1679 },
1680 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
1681 "unsigned Sx = DSP_R (x);",
1682 "int Sx_grd = GET_DSP_GRD (x);",
1683 "int i = 16;",
1684 "",
1685 "if (Sx_grd < 0)",
1686 " {",
1687 " Sx_grd = ~Sx_grd;",
1688 " Sx = ~Sx;",
1689 " }",
1690 "if (Sx_grd)",
1691 " {",
1692 " Sx = Sx_grd;",
1693 " res = -2;",
1694 " }",
1695 "else if (Sx)",
1696 " res = 30;",
1697 "else",
1698 " res = 31;",
1699 "do",
1700 " {",
1701 " if (Sx & ~0 << i)",
1702 " {",
1703 " res -= i;",
1704 " Sx >>= i;",
1705 " }",
1706 " }",
1707 "while (i >>= 1);",
1708 "res <<= 16;",
1709 "res_grd = SIGN32 (res);",
1710 "carry = 0;",
1711 "overflow = 0;",
1712 "ADD_SUB_GE;",
1713 },
1714 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
1715 "unsigned Sy = DSP_R (y);",
1716 "int i;",
1717 "",
1718 "if (Sy < 0)",
1719 " Sy = ~Sy;",
1720 "Sy <<= 1;",
1721 "res = 31;",
1722 "do",
1723 " {",
1724 " if (Sy & ~0 << i)",
1725 " {",
1726 " res -= i;",
1727 " Sy >>= i;",
1728 " }",
1729 " }",
1730 "while (i >>= 1);",
1731 "res <<= 16;",
1732 "res_grd = SIGN32 (res);",
1733 "carry = 0;",
1734 "overflow = 0;",
1735 "ADD_SUB_GE;",
1736 },
1737 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
1738 "int Sx = DSP_R (x);",
1739 "int Sx_grd = GET_DSP_GRD (x);",
1740 "",
1741 "res = 0 - Sx;",
1742 "carry = res != 0;",
1743 "res_grd = 0 - Sx_grd - carry;",
1744 "COMPUTE_OVERFLOW;",
1745 "ADD_SUB_GE;",
1746 },
1747 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
1748 "res = DSP_R (x);",
1749 "res_grd = GET_DSP_GRD (x);",
1750 "carry = 0;",
1751 "COMPUTE_OVERFLOW;",
1752 "ADD_SUB_GE;",
1753 },
1754 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
1755 "int Sy = DSP_R (y);",
1756 "int Sy_grd = SIGN32 (Sy);",
1757 "",
1758 "res = 0 - Sy;",
1759 "carry = res != 0;",
1760 "res_grd = 0 - Sy_grd - carry;",
1761 "COMPUTE_OVERFLOW;",
1762 "ADD_SUB_GE;",
1763 },
1764 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
1765 "res = DSP_R (y);",
1766 "res_grd = SIGN32 (res);",
1767 "carry = 0;",
1768 "COMPUTE_OVERFLOW;",
1769 "ADD_SUB_GE;",
1770 },
1771 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
1772 "res = MACH;",
1773 "res_grd = SIGN32 (res);",
1774 "goto assign_z;",
1775 },
1776 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
1777 "res = MACL;",
1778 "res_grd = SIGN32 (res);",
1779 "goto assign_z;",
1780 },
1781 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
1782 "if (0xa05f >> z & 1)",
1783 " RAISE_EXCEPTION (SIGILL);",
1784 "else",
1785 " MACH = DSP_R (z);",
1786 "return;",
1787 },
1788 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
1789 "if (0xa05f >> z & 1)",
1790 " RAISE_EXCEPTION (SIGILL);",
1791 "else",
1792 " MACL = DSP_R (z) = res;",
1793 "return;",
1794 },
1795 {0, 0}
1796 };
1797
1798 /* Tables of things to put into enums for sh-opc.h */
1799 static char *nibble_type_list[] =
1800 {
1801 "HEX_0",
1802 "HEX_1",
1803 "HEX_2",
1804 "HEX_3",
1805 "HEX_4",
1806 "HEX_5",
1807 "HEX_6",
1808 "HEX_7",
1809 "HEX_8",
1810 "HEX_9",
1811 "HEX_A",
1812 "HEX_B",
1813 "HEX_C",
1814 "HEX_D",
1815 "HEX_E",
1816 "HEX_F",
1817 "REG_N",
1818 "REG_M",
1819 "BRANCH_12",
1820 "BRANCH_8",
1821 "DISP_8",
1822 "DISP_4",
1823 "IMM_4",
1824 "IMM_4BY2",
1825 "IMM_4BY4",
1826 "PCRELIMM_8BY2",
1827 "PCRELIMM_8BY4",
1828 "IMM_8",
1829 "IMM_8BY2",
1830 "IMM_8BY4",
1831 0
1832 };
1833 static
1834 char *arg_type_list[] =
1835 {
1836 "A_END",
1837 "A_BDISP12",
1838 "A_BDISP8",
1839 "A_DEC_M",
1840 "A_DEC_N",
1841 "A_DISP_GBR",
1842 "A_DISP_PC",
1843 "A_DISP_REG_M",
1844 "A_DISP_REG_N",
1845 "A_GBR",
1846 "A_IMM",
1847 "A_INC_M",
1848 "A_INC_N",
1849 "A_IND_M",
1850 "A_IND_N",
1851 "A_IND_R0_REG_M",
1852 "A_IND_R0_REG_N",
1853 "A_MACH",
1854 "A_MACL",
1855 "A_PR",
1856 "A_R0",
1857 "A_R0_GBR",
1858 "A_REG_M",
1859 "A_REG_N",
1860 "A_SR",
1861 "A_VBR",
1862 "A_SSR",
1863 "A_SPC",
1864 0,
1865 };
1866
1867 static void
1868 make_enum_list (name, s)
1869 char *name;
1870 char **s;
1871 {
1872 int i = 1;
1873 printf ("typedef enum {\n");
1874 while (*s)
1875 {
1876 printf ("\t%s,\n", *s);
1877 s++;
1878 i++;
1879 }
1880 printf ("} %s;\n", name);
1881 }
1882
1883 static int
1884 qfunc (a, b)
1885 op *a;
1886 op *b;
1887 {
1888 char bufa[9];
1889 char bufb[9];
1890 int diff;
1891
1892 memcpy (bufa, a->code, 4);
1893 memcpy (bufa + 4, a->code + 12, 4);
1894 bufa[8] = 0;
1895
1896 memcpy (bufb, b->code, 4);
1897 memcpy (bufb + 4, b->code + 12, 4);
1898 bufb[8] = 0;
1899 diff = strcmp (bufa, bufb);
1900 /* Stabilize the sort, so that later entries can override more general
1901 preceding entries. */
1902 return diff ? diff : a - b;
1903 }
1904
1905 static void
1906 sorttab ()
1907 {
1908 op *p = tab;
1909 int len = 0;
1910
1911 while (p->name)
1912 {
1913 p++;
1914 len++;
1915 }
1916 qsort (tab, len, sizeof (*p), qfunc);
1917 }
1918
1919 static void
1920 gengastab ()
1921 {
1922 op *p;
1923 sorttab ();
1924 for (p = tab; p->name; p++)
1925 {
1926 printf ("%s %-30s\n", p->code, p->name);
1927 }
1928
1929
1930 }
1931
1932 /* Convert a string of 4 binary digits into an int */
1933
1934 static
1935 int
1936 bton (s)
1937 char *s;
1938
1939 {
1940 int n = 0;
1941 int v = 8;
1942 while (v)
1943 {
1944 if (*s == '1')
1945 n |= v;
1946 v >>= 1;
1947 s++;
1948 }
1949 return n;
1950 }
1951
1952 static unsigned char table[1 << 16];
1953
1954 /* Take an opcode expand all varying fields in it out and fill all the
1955 right entries in 'table' with the opcode index*/
1956
1957 static void
1958 expand_opcode (shift, val, i, s)
1959 int shift;
1960 int val;
1961 int i;
1962 char *s;
1963 {
1964 int j;
1965
1966 if (*s == 0)
1967 {
1968 table[val] = i;
1969 }
1970 else
1971 {
1972 switch (s[0])
1973 {
1974
1975 case '0':
1976 case '1':
1977 {
1978 int m, mv;
1979
1980 val |= bton (s) << shift;
1981 if (s[2] == '0' || s[2] == '1')
1982 expand_opcode (shift - 4, val, i, s + 4);
1983 else if (s[2] == 'N')
1984 for (j = 0; j < 4; j++)
1985 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1986 else if (s[2] == 'x')
1987 for (j = 0; j < 4; j += 2)
1988 for (m = 0; m < 32; m++)
1989 {
1990 /* Ignore illegal nopy */
1991 if ((m & 7) == 0 && m != 0)
1992 continue;
1993 mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
1994 expand_opcode (shift - 4, val | mv | (j << shift), i,
1995 s + 4);
1996 }
1997 else if (s[2] == 'y')
1998 for (j = 0; j < 2; j++)
1999 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2000 break;
2001 }
2002 case 'n':
2003 case 'm':
2004 for (j = 0; j < 16; j++)
2005 {
2006 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2007
2008 }
2009 break;
2010 case 'M':
2011 /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2012 for (j = 5; j < 16; j++)
2013 if (j != 6)
2014 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2015 break;
2016 case 'G':
2017 /* A1G, A0G: */
2018 for (j = 13; j <= 15; j +=2)
2019 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2020 break;
2021 case 's':
2022 /* System registers mach, macl, pr: */
2023 for (j = 0; j < 3; j++)
2024 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2025 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2026 for (j = 5; j < 12; j++)
2027 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2028 break;
2029 case 'X':
2030 case 'a':
2031 val |= bton (s) << shift;
2032 for (j = 0; j < 16; j += 8)
2033 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2034 break;
2035 case 'Y':
2036 case 'A':
2037 val |= bton (s) << shift;
2038 for (j = 0; j < 8; j += 4)
2039 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2040 break;
2041
2042 default:
2043 for (j = 0; j < (1 << (shift + 4)); j++)
2044 {
2045 table[val | j] = i;
2046 }
2047 }
2048 }
2049 }
2050
2051 /* Print the jump table used to index an opcode into a switch
2052 statement entry. */
2053
2054 static void
2055 dumptable (name, size, start)
2056 char *name;
2057 int size;
2058 int start;
2059 {
2060 int lump = 256;
2061 int online = 16;
2062
2063 int i = start;
2064
2065 printf ("unsigned char %s[%d]={\n", name, size);
2066 while (i < start + size)
2067 {
2068 int j = 0;
2069
2070 printf ("/* 0x%x */\n", i);
2071
2072 while (j < lump)
2073 {
2074 int k = 0;
2075 while (k < online)
2076 {
2077 printf ("%2d", table[i + j + k]);
2078 if (j + k < lump)
2079 printf (",");
2080
2081 k++;
2082 }
2083 j += k;
2084 printf ("\n");
2085 }
2086 i += j;
2087 }
2088 printf ("};\n");
2089 }
2090
2091
2092 static void
2093 filltable (p)
2094 op *p;
2095 {
2096 static int index = 1;
2097
2098 sorttab ();
2099 for (; p->name; p++)
2100 {
2101 p->index = index++;
2102 expand_opcode (12, 0, p->index, p->code);
2103 }
2104 }
2105
2106 /* Table already contais all the switch case tags for 16-bit opcode double
2107 data transfer (ddt) insns, and the switch case tag for processing parallel
2108 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2109 latter tag to represent all combinations of ppi with ddt. */
2110 static void
2111 ppi_moves ()
2112 {
2113 int i;
2114
2115 for (i = 0xf000; i < 0xf400; i++)
2116 if (table[i])
2117 table[i + 0x800] = table[0xf800];
2118 }
2119
2120 static void
2121 gensim_caselist (p)
2122 op *p;
2123 {
2124 for (; p->name; p++)
2125 {
2126 int j;
2127 int sextbit = -1;
2128 int needm = 0;
2129 int needn = 0;
2130
2131 char *s = p->code;
2132
2133 printf (" /* %s %s */\n", p->name, p->code);
2134 printf (" case %d: \n", p->index);
2135
2136 printf (" {\n");
2137 while (*s)
2138 {
2139 switch (*s)
2140 {
2141 case '0':
2142 case '1':
2143 s += 2;
2144 break;
2145 case '.':
2146 s += 4;
2147 break;
2148 case 'n':
2149 printf (" int n = (iword >>8) & 0xf;\n");
2150 needn = 1;
2151 s += 4;
2152 break;
2153 case 'N':
2154 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2155 s += 2;
2156 break;
2157 case 'x':
2158 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2159 needn = 1;
2160 s += 2;
2161 break;
2162 case 'y':
2163 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2164 needn = 1;
2165 s += 2;
2166 break;
2167 case 'm':
2168 needm = 1;
2169 case 's':
2170 case 'M':
2171 case 'G':
2172 printf (" int m = (iword >>4) & 0xf;\n");
2173 s += 4;
2174 break;
2175 case 'X':
2176 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2177 s += 2;
2178 break;
2179 case 'a':
2180 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2181 s += 2;
2182 break;
2183 case 'Y':
2184 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2185 s += 2;
2186 break;
2187 case 'A':
2188 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2189 s += 2;
2190 break;
2191
2192 case 'i':
2193 printf (" int i = (iword & 0x");
2194
2195 switch (s[1])
2196 {
2197 case '4':
2198 printf ("f");
2199 break;
2200 case '8':
2201 printf ("ff");
2202 break;
2203 case '1':
2204 sextbit = 12;
2205
2206 printf ("fff");
2207 break;
2208 }
2209 printf (")");
2210
2211 switch (s[3])
2212 {
2213 case '1':
2214 break;
2215 case '2':
2216 printf ("<<1");
2217 break;
2218 case '4':
2219 printf ("<<2");
2220 break;
2221 }
2222 printf (";\n");
2223 s += 4;
2224 }
2225 }
2226 if (sextbit > 0)
2227 {
2228 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
2229 sextbit - 1, sextbit - 1);
2230 }
2231
2232 if (needm && needn)
2233 printf (" TB(m,n);\n");
2234 else if (needm)
2235 printf (" TL(m);\n");
2236 else if (needn)
2237 printf (" TL(n);\n");
2238
2239 {
2240 /* Do the refs */
2241 char *r;
2242 for (r = p->refs; *r; r++)
2243 {
2244 if (*r == '0') printf(" CREF(0);\n");
2245 if (*r == '8') printf(" CREF(8);\n");
2246 if (*r == '9') printf(" CREF(9);\n");
2247 if (*r == 'n') printf(" CREF(n);\n");
2248 if (*r == 'm') printf(" CREF(m);\n");
2249 }
2250 }
2251
2252 printf (" {\n");
2253 for (j = 0; j < MAX_NR_STUFF; j++)
2254 {
2255 if (p->stuff[j])
2256 {
2257 printf (" %s\n", p->stuff[j]);
2258 }
2259 }
2260 printf (" }\n");
2261
2262 {
2263 /* Do the defs */
2264 char *r;
2265 for (r = p->defs; *r; r++)
2266 {
2267 if (*r == '0') printf(" CDEF(0);\n");
2268 if (*r == 'n') printf(" CDEF(n);\n");
2269 if (*r == 'm') printf(" CDEF(m);\n");
2270 }
2271 }
2272
2273 printf (" break;\n");
2274 printf (" }\n");
2275 }
2276 }
2277
2278 static void
2279 gensim ()
2280 {
2281 printf ("{\n");
2282 printf (" switch (jump_table[iword]) {\n");
2283
2284 gensim_caselist (tab);
2285 gensim_caselist (movsxy_tab);
2286
2287 printf (" default:\n");
2288 printf (" {\n");
2289 printf (" RAISE_EXCEPTION (SIGILL);\n");
2290 printf (" }\n");
2291 printf (" }\n");
2292 printf ("}\n");
2293 }
2294
2295 static void
2296 gendefines ()
2297 {
2298 op *p;
2299 filltable (tab);
2300 for (p = tab; p->name; p++)
2301 {
2302 char *s = p->name;
2303 printf ("#define OPC_");
2304 while (*s) {
2305 if (isupper(*s))
2306 *s = tolower(*s);
2307 if (isalpha(*s)) printf("%c", *s);
2308 if (*s == ' ') printf("_");
2309 if (*s == '@') printf("ind_");
2310 if (*s == ',') printf("_");
2311 s++;
2312 }
2313 printf(" %d\n",p->index);
2314 }
2315 }
2316
2317 static int ppi_index;
2318
2319 /* Take an ppi code, expand all varying fields in it and fill all the
2320 right entries in 'table' with the opcode index. */
2321
2322 static void
2323 expand_ppi_code (val, i, s)
2324 int val;
2325 int i;
2326 char *s;
2327 {
2328 int j;
2329
2330 for (;;)
2331 {
2332 switch (s[0])
2333 {
2334 /* The last eight bits are disregarded for the switch table. */
2335 case 'm':
2336 case 'x':
2337 case '.':
2338 table[val] = i;
2339 return;
2340 case '0':
2341 val += val;
2342 s++;
2343 break;
2344 case '1':
2345 val += val + 1;
2346 s++;
2347 break;
2348 case 'i':
2349 case 'e': case 'f':
2350 val += val;
2351 s++;
2352 expand_ppi_code (val, i, s);
2353 val++;
2354 break;
2355 case 'c':
2356 val <<= 2;
2357 s += 2;
2358 val++;
2359 expand_ppi_code (val, ppi_index++, s);
2360 val++;
2361 expand_ppi_code (val, i, s);
2362 val++;
2363 break;
2364 }
2365 }
2366 }
2367
2368 static void
2369 ppi_filltable ()
2370 {
2371 op *p;
2372 ppi_index = 1;
2373
2374 for (p = ppi_tab; p->name; p++)
2375 {
2376 p->index = ppi_index++;
2377 expand_ppi_code (0, p->index, p->code);
2378 }
2379 }
2380
2381 static void
2382 ppi_gensim ()
2383 {
2384 op *p = ppi_tab;
2385
2386 printf ("#define DSR_MASK_G 0x80\n");
2387 printf ("#define DSR_MASK_Z 0x40\n");
2388 printf ("#define DSR_MASK_N 0x20\n");
2389 printf ("#define DSR_MASK_V 0x10\n");
2390 printf ("\n");
2391 printf ("#define COMPUTE_OVERFLOW do {\\\n");
2392 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2393 printf (" if (overflow && S) \\\n");
2394 printf (" { \\\n");
2395 printf (" if (res_grd & 0x80) \\\n");
2396 printf (" { \\\n");
2397 printf (" res = 0x80000000; \\\n");
2398 printf (" res_grd |= 0xff; \\\n");
2399 printf (" } \\\n");
2400 printf (" else \\\n");
2401 printf (" { \\\n");
2402 printf (" res = 0x7fffffff; \\\n");
2403 printf (" res_grd &= ~0xff; \\\n");
2404 printf (" } \\\n");
2405 printf (" overflow = 0; \\\n");
2406 printf (" } \\\n");
2407 printf ("} while (0)\n");
2408 printf ("\n");
2409 printf ("#define ADD_SUB_GE \\\n");
2410 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2411 printf ("\n");
2412 printf ("static void\n");
2413 printf ("ppi_insn (iword)\n");
2414 printf (" int iword;\n");
2415 printf ("{\n");
2416 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
2417 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
2418 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
2419 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
2420 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
2421 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
2422 printf ("\n");
2423 printf (" int z;\n");
2424 printf (" int res, res_grd;\n");
2425 printf (" int carry, overflow, greater_equal;\n");
2426 printf ("\n");
2427 printf (" switch (ppi_table[iword >> 8]) {\n");
2428
2429 for (; p->name; p++)
2430 {
2431 int shift, j;
2432 int cond = 0;
2433 int havedecl = 0;
2434
2435 char *s = p->code;
2436
2437 printf (" /* %s %s */\n", p->name, p->code);
2438 printf (" case %d: \n", p->index);
2439
2440 printf (" {\n");
2441 for (shift = 16; *s; )
2442 {
2443 switch (*s)
2444 {
2445 case 'i':
2446 printf (" int i = (iword >> 4) & 0x7f;\n");
2447 s += 6;
2448 break;
2449 case 'e':
2450 case 'f':
2451 case 'x':
2452 case 'y':
2453 case 'g':
2454 case 'u':
2455 shift -= 2;
2456 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
2457 *s, *s, shift);
2458 havedecl = 1;
2459 s += 2;
2460 break;
2461 case 'c':
2462 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2463 printf ("\tbreak;\n");
2464 printf (" }\n");
2465 printf (" case %d: \n", p->index + 1);
2466 printf (" {\n");
2467 cond = 1;
2468 case '0':
2469 case '1':
2470 case '.':
2471 shift -= 2;
2472 s += 2;
2473 break;
2474 case 'z':
2475 if (havedecl)
2476 printf ("\n");
2477 printf (" z = iword & 0xf;\n");
2478 havedecl = 2;
2479 s += 4;
2480 break;
2481 }
2482 }
2483 if (havedecl == 1)
2484 printf ("\n");
2485 else if (havedecl == 2)
2486 printf (" {\n");
2487 for (j = 0; j < MAX_NR_STUFF; j++)
2488 {
2489 if (p->stuff[j])
2490 {
2491 printf (" %s%s\n",
2492 (havedecl == 2 ? " " : ""),
2493 p->stuff[j]);
2494 }
2495 }
2496 if (havedecl == 2)
2497 printf (" }\n");
2498 if (cond)
2499 {
2500 printf (" if (iword & 0x200)\n");
2501 printf (" goto assign_z;\n");
2502 }
2503 printf (" break;\n");
2504 printf (" }\n");
2505 }
2506
2507 printf (" default:\n");
2508 printf (" {\n");
2509 printf (" RAISE_EXCEPTION (SIGILL);\n");
2510 printf (" return;\n");
2511 printf (" }\n");
2512 printf (" }\n");
2513 printf (" DSR &= ~0xf1;\n");
2514 printf (" if (res || res_grd)\n");
2515 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2516 printf (" else\n");
2517 printf (" DSR |= DSR_MASK_Z | overflow;\n");
2518 printf (" assign_dc:\n");
2519 printf (" switch (DSR >> 1 & 7)\n");
2520 printf (" {\n");
2521 printf (" case 0: /* Carry Mode */\n");
2522 printf (" DSR |= carry;\n");
2523 printf (" case 1: /* Negative Value Mode */\n");
2524 printf (" DSR |= res_grd >> 7 & 1;\n");
2525 printf (" case 2: /* Zero Value Mode */\n");
2526 printf (" DSR |= DSR >> 6 & 1;\n");
2527 printf (" case 3: /* Overflow mode\n");
2528 printf (" DSR |= overflow >> 4;\n");
2529 printf (" case 4: /* Signed Greater Than Mode */\n");
2530 printf (" DSR |= DSR >> 7 & 1;\n");
2531 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
2532 printf (" DSR |= greater_equal >> 7;\n");
2533 printf (" }\n");
2534 printf (" assign_z:\n");
2535 printf (" if (0xa05f >> z & 1)\n");
2536 printf (" {\n");
2537 printf (" RAISE_EXCEPTION (SIGILL);\n");
2538 printf (" return;\n");
2539 printf (" }\n");
2540 printf (" DSP_R (z) = res;\n");
2541 printf (" DSP_GRD (z) = res_grd;\n");
2542 printf ("}\n");
2543 }
2544
2545 int
2546 main (ac, av)
2547 int ac;
2548 char **av;
2549 {
2550 /* verify the table before anything else */
2551 {
2552 op *p;
2553 for (p = tab; p->name; p++)
2554 {
2555 /* check that the code field contains 16 bits */
2556 if (strlen (p->code) != 16)
2557 {
2558 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2559 p->code, strlen (p->code), p->name);
2560 abort ();
2561 }
2562 }
2563 }
2564
2565 /* now generate the requested data */
2566 if (ac > 1)
2567 {
2568 if (strcmp (av[1], "-t") == 0)
2569 {
2570 gengastab ();
2571 }
2572 else if (strcmp (av[1], "-d") == 0)
2573 {
2574 gendefines ();
2575 }
2576 else if (strcmp (av[1], "-s") == 0)
2577 {
2578 filltable (tab);
2579 dumptable ("sh_jump_table", 1 << 16, 0);
2580
2581 memset (table, 0, sizeof table);
2582 filltable (movsxy_tab);
2583 ppi_moves ();
2584 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2585
2586 memset (table, 0, sizeof table);
2587 ppi_filltable ();
2588 dumptable ("ppi_table", 1 << 8, 0);
2589 }
2590 else if (strcmp (av[1], "-x") == 0)
2591 {
2592 filltable (tab);
2593 filltable (movsxy_tab);
2594 gensim ();
2595 }
2596 else if (strcmp (av[1], "-p") == 0)
2597 {
2598 ppi_filltable ();
2599 ppi_gensim ();
2600 }
2601 }
2602 else
2603 fprintf (stderr, "Opcode table generation no longer supported.\n");
2604 return 0;
2605 }
This page took 0.11367 seconds and 4 git commands to generate.