daily update
[deliverable/binutils-gdb.git] / sim / sh / gencode.c
... / ...
CommitLineData
1/* Simulator/Opcode generator for the Renesas
2 (formerly Hitachi) / SuperH Inc. Super-H architecture.
3
4 Written by Steve Chamberlain of Cygnus Support.
5 sac@cygnus.com
6
7 This file is part of SH sim.
8
9
10 THIS SOFTWARE IS NOT COPYRIGHTED
11
12 Cygnus offers the following for use in the public domain. Cygnus
13 makes no warranty with regard to the software or it's performance
14 and the user accepts the software "AS IS" with all faults.
15
16 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
17 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
20*/
21
22/* This program generates the opcode table for the assembler and
23 the simulator code.
24
25 -t prints a pretty table for the assembler manual
26 -s generates the simulator code jump table
27 -d generates a define table
28 -x generates the simulator code switch statement
29 default used to generate the opcode tables
30
31*/
32
33#include <stdio.h>
34
35#define MAX_NR_STUFF 42
36
37typedef struct
38{
39 char *defs;
40 char *refs;
41 char *name;
42 char *code;
43 char *stuff[MAX_NR_STUFF];
44 int index;
45} op;
46
47
48op tab[] =
49{
50
51 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
52 "R[n] += SEXT (i);",
53 "if (i == 0) {",
54 " UNDEF(n); /* see #ifdef PARANOID */",
55 " break;",
56 "}",
57 },
58 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
59 "R[n] += R[m];",
60 },
61
62 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
63 "ult = R[n] + T;",
64 "SET_SR_T (ult < R[n]);",
65 "R[n] = ult + R[m];",
66 "SET_SR_T (T || (R[n] < ult));",
67 },
68
69 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
70 "ult = R[n] + R[m];",
71 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
72 "R[n] = ult;",
73 },
74
75 { "0", "0", "and #<imm>,R0", "11001001i8*1....",
76 "R0 &= i;",
77 },
78 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
79 "R[n] &= R[m];",
80 },
81 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
82 "MA (1);",
83 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
84 },
85
86 { "", "", "bf <bdisp8>", "10001011i8p1....",
87 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
88 "if (!T) {",
89 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
90 " cycles += 2;",
91 "}",
92 },
93
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
96 "if (!T) {",
97 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
98 " cycles += 2;",
99 " Delay_Slot (PC + 2);",
100 "}",
101 },
102
103 { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
104 "/* 32-bit logical bit-manipulation instructions. */",
105 "int word2 = RIAT (nip);",
106 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
107 "i >>= 4; /* BOGUS: Using only three bits of 'i'. */",
108 "/* MSB of 'i' must be zero. */",
109 "if (i > 7)",
110 " RAISE_EXCEPTION (SIGILL);",
111 "MA (1);",
112 "do_blog_insn (1 << i, (word2 & 0xfff) + R[n], ",
113 " (word2 >> 12) & 0xf, memory, maskb);",
114 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
115 },
116 { "", "", "bra <bdisp12>", "1010i12.........",
117 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
118 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
119 "cycles += 2;",
120 "Delay_Slot (PC + 2);",
121 },
122
123 { "", "n", "braf <REG_N>", "0000nnnn00100011",
124 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
125 "SET_NIP (PC + 4 + R[n]);",
126 "cycles += 2;",
127 "Delay_Slot (PC + 2);",
128 },
129
130 { "", "", "bsr <bdisp12>", "1011i12.........",
131 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
132 "PR = PH2T (PC + 4);",
133 "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
134 "cycles += 2;",
135 "Delay_Slot (PC + 2);",
136 },
137
138 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
139 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
140 "PR = PH2T (PC) + 4;",
141 "SET_NIP (PC + 4 + R[n]);",
142 "cycles += 2;",
143 "Delay_Slot (PC + 2);",
144 },
145
146 { "", "", "bt <bdisp8>", "10001001i8p1....",
147 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
148 "if (T) {",
149 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
150 " cycles += 2;",
151 "}",
152 },
153
154 { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
155 "/* MSB of 'i' is true for load, false for store. */",
156 "if (i <= 7)",
157 " if (T)",
158 " R[m] |= (1 << i);",
159 " else",
160 " R[m] &= ~(1 << i);",
161 "else",
162 " SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
163 },
164 { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
165 "/* MSB of 'i' is true for set, false for clear. */",
166 "if (i <= 7)",
167 " R[m] &= ~(1 << i);",
168 "else",
169 " R[m] |= (1 << (i - 8));",
170 },
171 { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
172 "if (R[n] < -128 || R[n] > 127) {",
173 " L (n);",
174 " SET_SR_CS (1);",
175 " if (R[n] > 127)",
176 " R[n] = 127;",
177 " else if (R[n] < -128)",
178 " R[n] = -128;",
179 "}",
180 },
181 { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
182 "if (R[n] < -32768 || R[n] > 32767) {",
183 " L (n);",
184 " SET_SR_CS (1);",
185 " if (R[n] > 32767)",
186 " R[n] = 32767;",
187 " else if (R[n] < -32768)",
188 " R[n] = -32768;",
189 "}",
190 },
191 { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
192 "if (R[n] < -256 || R[n] > 255) {",
193 " L (n);",
194 " SET_SR_CS (1);",
195 " R[n] = 255;",
196 "}",
197 },
198 { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
199 "if (R[n] < -65536 || R[n] > 65535) {",
200 " L (n);",
201 " SET_SR_CS (1);",
202 " R[n] = 65535;",
203 "}",
204 },
205 { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
206 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
207 "if (R0 == 0)",
208 " R[n] = 0x7fffffff;",
209 "else if (R0 == -1 && R[n] == 0x80000000)",
210 " R[n] = 0x7fffffff;",
211 "else R[n] /= R0;",
212 "L (n);",
213 },
214 { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
215 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
216 "if (R0 == 0)",
217 " R[n] = 0xffffffff;",
218 "else (unsigned int) R[n] = (unsigned int) R[n] / (unsigned int) R0;",
219 "L (n);",
220 },
221 { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
222 "R[n] = (R[n] * R0) & 0xffffffff;",
223 "L (n);",
224 },
225 { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
226 "int regn = (R[n] >> 2) & 0x1f;",
227 "int bankn = (R[n] >> 7) & 0x1ff;",
228 "if (regn > 19)",
229 " regn = 19; /* FIXME what should happen? */",
230 "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
231 "L (0);",
232 },
233 { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
234 "int regn = (R[n] >> 2) & 0x1f;",
235 "int bankn = (R[n] >> 7) & 0x1ff;",
236 "if (regn > 19)",
237 " regn = 19; /* FIXME what should happen? */",
238 "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
239 },
240 { "", "", "resbank", "0000000001011011",
241 "int i;",
242 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
243 /* FIXME: cdef all */
244 "if (BO) { /* Bank Overflow */",
245 /* FIXME: how do we know when to reset BO? */
246 " for (i = 0; i <= 14; i++) {",
247 " R[i] = RLAT (R[15]);",
248 " MA (1);",
249 " R[15] += 4;",
250 " }",
251 " PR = RLAT (R[15]);",
252 " R[15] += 4;",
253 " MA (1);",
254 " GBR = RLAT (R[15]);",
255 " R[15] += 4;",
256 " MA (1);",
257 " MACH = RLAT (R[15]);",
258 " R[15] += 4;",
259 " MA (1);",
260 " MACL = RLAT (R[15]);",
261 " R[15] += 4;",
262 " MA (1);",
263 "}",
264 "else if (BANKN == 0) /* Bank Underflow */",
265 " RAISE_EXCEPTION (SIGILL);", /* FIXME: what exception? */
266 "else {",
267 " SET_BANKN (BANKN - 1);",
268 " for (i = 0; i <= 14; i++)",
269 " R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
270 " MACH = saved_state.asregs.regstack[BANKN].regs[15];",
271 " PR = saved_state.asregs.regstack[BANKN].regs[17];",
272 " GBR = saved_state.asregs.regstack[BANKN].regs[18];",
273 " MACL = saved_state.asregs.regstack[BANKN].regs[19];",
274 "}",
275 },
276 { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
277 "/* Push Rn...R0 (if n==15, push pr and R14...R0). */",
278 "do {",
279 " MA (1);",
280 " R[15] -= 4;",
281 " if (n == 15)",
282 " WLAT (R[15], PR);",
283 " else",
284 " WLAT (R[15], R[n]);",
285 "} while (n-- > 0);",
286 },
287 { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
288 "/* Pop R0...Rn (if n==15, pop R0...R14 and pr). */",
289 "int i = 0;\n",
290 "do {",
291 " MA (1);",
292 " if (i == 15)",
293 " PR = RLAT (R[15]);",
294 " else",
295 " R[i] = RLAT (R[15]);",
296 " R[15] += 4;",
297 "} while (i++ < n);",
298 },
299 { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
300 "/* Push pr, R14...Rn (if n==15, push pr). */", /* FIXME */
301 "int i = 15;\n",
302 "do {",
303 " MA (1);",
304 " R[15] -= 4;",
305 " if (i == 15)",
306 " WLAT (R[15], PR);",
307 " else",
308 " WLAT (R[15], R[i]);",
309 "} while (i-- > n);",
310 },
311 { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
312 "/* Pop Rn...R14, pr (if n==15, pop pr). */", /* FIXME */
313 "do {",
314 " MA (1);",
315 " if (n == 15)",
316 " PR = RLAT (R[15]);",
317 " else",
318 " R[n] = RLAT (R[15]);",
319 " R[15] += 4;",
320 "} while (n++ < 15);",
321 },
322 { "", "", "nott", "0000000001101000",
323 "SET_SR_T (T == 0);",
324 },
325
326 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
327 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
328 "if (T) {",
329 " SET_NIP (PC + 4 + (SEXT (i) * 2));",
330 " cycles += 2;",
331 " Delay_Slot (PC + 2);",
332 "}",
333 },
334
335 { "", "", "clrmac", "0000000000101000",
336 "MACH = 0;",
337 "MACL = 0;",
338 },
339
340 { "", "", "clrs", "0000000001001000",
341 "SET_SR_S (0);",
342 },
343
344 { "", "", "clrt", "0000000000001000",
345 "SET_SR_T (0);",
346 },
347
348 /* sh4a */
349 { "", "", "clrdmxy", "0000000010001000",
350 "saved_state.asregs.cregs.named.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
351 },
352
353 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
354 "SET_SR_T (R0 == SEXT (i));",
355 },
356 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
357 "SET_SR_T (R[n] == R[m]);",
358 },
359 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
360 "SET_SR_T (R[n] >= R[m]);",
361 },
362 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
363 "SET_SR_T (R[n] > R[m]);",
364 },
365 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
366 "SET_SR_T (UR[n] > UR[m]);",
367 },
368 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
369 "SET_SR_T (UR[n] >= UR[m]);",
370 },
371 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
372 "SET_SR_T (R[n] > 0);",
373 },
374 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
375 "SET_SR_T (R[n] >= 0);",
376 },
377 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
378 "ult = R[n] ^ R[m];",
379 "SET_SR_T (((ult & 0xff000000) == 0)",
380 " | ((ult & 0xff0000) == 0)",
381 " | ((ult & 0xff00) == 0)",
382 " | ((ult & 0xff) == 0));",
383 },
384
385 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
386 "SET_SR_Q ((R[n] & sbit) != 0);",
387 "SET_SR_M ((R[m] & sbit) != 0);",
388 "SET_SR_T (M != Q);",
389 },
390
391 { "", "", "div0u", "0000000000011001",
392 "SET_SR_M (0);",
393 "SET_SR_Q (0);",
394 "SET_SR_T (0);",
395 },
396
397 { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
398 "div1 (&R0, m, n/*, T*/);",
399 },
400
401 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
402 "dmul (1/*signed*/, R[n], R[m]);",
403 },
404
405 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
406 "dmul (0/*unsigned*/, R[n], R[m]);",
407 },
408
409 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
410 "R[n]--;",
411 "SET_SR_T (R[n] == 0);",
412 },
413
414 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
415 "R[n] = SEXT (R[m]);",
416 },
417 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
418 "R[n] = SEXTW (R[m]);",
419 },
420
421 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
422 "R[n] = (R[m] & 0xff);",
423 },
424 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
425 "R[n] = (R[m] & 0xffff);",
426 },
427
428 /* sh2e */
429 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
430 "FP_UNARY (n, fabs);",
431 "/* FIXME: FR (n) &= 0x7fffffff; */",
432 },
433
434 /* sh2e */
435 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
436 "FP_OP (n, +, m);",
437 },
438
439 /* sh2e */
440 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
441 "FP_CMP (n, ==, m);",
442 },
443 /* sh2e */
444 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
445 "FP_CMP (n, >, m);",
446 },
447
448 /* sh4 */
449 { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
450 "if (! FPSCR_PR || n & 1)",
451 " RAISE_EXCEPTION (SIGILL);",
452 "else",
453 "{",
454 " union",
455 " {",
456 " int i;",
457 " float f;",
458 " } u;",
459 " u.f = DR (n);",
460 " FPUL = u.i;",
461 "}",
462 },
463
464 /* sh4 */
465 { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
466 "if (! FPSCR_PR || n & 1)",
467 " RAISE_EXCEPTION (SIGILL);",
468 "else",
469 "{",
470 " union",
471 " {",
472 " int i;",
473 " float f;",
474 " } u;",
475 " u.i = FPUL;",
476 " SET_DR (n, u.f);",
477 "}",
478 },
479
480 /* sh2e */
481 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
482 "FP_OP (n, /, m);",
483 "/* FIXME: check for DP and (n & 1) == 0? */",
484 },
485
486 /* sh4 */
487 { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
488 "if (FPSCR_PR)",
489 " RAISE_EXCEPTION (SIGILL);",
490 "else",
491 "{",
492 " double fsum = 0;",
493 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
494 " RAISE_EXCEPTION (SIGILL);",
495 " /* FIXME: check for nans and infinities. */",
496 " fsum += FR (v1+0) * FR (v2+0);",
497 " fsum += FR (v1+1) * FR (v2+1);",
498 " fsum += FR (v1+2) * FR (v2+2);",
499 " fsum += FR (v1+3) * FR (v2+3);",
500 " SET_FR (v1+3, fsum);",
501 "}",
502 },
503
504 /* sh2e */
505 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
506 "SET_FR (n, (float) 0.0);",
507 "/* FIXME: check for DP and (n & 1) == 0? */",
508 },
509
510 /* sh2e */
511 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
512 "SET_FR (n, (float) 1.0);",
513 "/* FIXME: check for DP and (n & 1) == 0? */",
514 },
515
516 /* sh2e */
517 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
518 " union",
519 " {",
520 " int i;",
521 " float f;",
522 " } u;",
523 " u.f = FR (n);",
524 " FPUL = u.i;",
525 },
526
527 /* sh2e */
528 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
529 /* sh4 */
530 "if (FPSCR_PR)",
531 " SET_DR (n, (double) FPUL);",
532 "else",
533 "{",
534 " SET_FR (n, (float) FPUL);",
535 "}",
536 },
537
538 /* sh2e */
539 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
540 "SET_FR (n, FR (m) * FR (0) + FR (n));",
541 "/* FIXME: check for DP and (n & 1) == 0? */",
542 },
543
544 /* sh2e */
545 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
546 /* sh4 */
547 "if (FPSCR_SZ) {",
548 " int ni = XD_TO_XF (n);",
549 " int mi = XD_TO_XF (m);",
550 " SET_XF (ni + 0, XF (mi + 0));",
551 " SET_XF (ni + 1, XF (mi + 1));",
552 "}",
553 "else",
554 "{",
555 " SET_FR (n, FR (m));",
556 "}",
557 },
558 /* sh2e */
559 { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
560 /* sh4 */
561 "if (FPSCR_SZ) {",
562 " MA (2);",
563 " WDAT (R[n], m);",
564 "}",
565 "else",
566 "{",
567 " MA (1);",
568 " WLAT (R[n], FI (m));",
569 "}",
570 },
571 /* sh2e */
572 { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
573 /* sh4 */
574 "if (FPSCR_SZ) {",
575 " MA (2);",
576 " RDAT (R[m], n);",
577 "}",
578 "else",
579 "{",
580 " MA (1);",
581 " SET_FI (n, RLAT (R[m]));",
582 "}",
583 },
584 /* sh2a */
585 { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
586 "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
587 " and mov.bwl <REG_N>, @(disp12,<REG_M>)",
588 " and mov.bwl @(disp12,<REG_N>),<REG_M>",
589 " and movu.bw @(disp12,<REG_N>),<REG_M>. */",
590 "int word2 = RIAT (nip);",
591 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
592 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
593 "MA (1);",
594 "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
595 },
596 /* sh2e */
597 { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
598 /* sh4 */
599 "if (FPSCR_SZ) {",
600 " MA (2);",
601 " RDAT (R[m], n);",
602 " R[m] += 8;",
603 "}",
604 "else",
605 "{",
606 " MA (1);",
607 " SET_FI (n, RLAT (R[m]));",
608 " R[m] += 4;",
609 "}",
610 },
611 /* sh2e */
612 { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
613 /* sh4 */
614 "if (FPSCR_SZ) {",
615 " MA (2);",
616 " R[n] -= 8;",
617 " WDAT (R[n], m);",
618 "}",
619 "else",
620 "{",
621 " MA (1);",
622 " R[n] -= 4;",
623 " WLAT (R[n], FI (m));",
624 "}",
625 },
626 /* sh2e */
627 { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
628 /* sh4 */
629 "if (FPSCR_SZ) {",
630 " MA (2);",
631 " RDAT (R[0]+R[m], n);",
632 "}",
633 "else",
634 "{",
635 " MA (1);",
636 " SET_FI (n, RLAT (R[0] + R[m]));",
637 "}",
638 },
639 /* sh2e */
640 { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
641 /* sh4 */
642 "if (FPSCR_SZ) {",
643 " MA (2);",
644 " WDAT (R[0]+R[n], m);",
645 "}",
646 "else",
647 "{",
648 " MA (1);",
649 " WLAT ((R[0]+R[n]), FI (m));",
650 "}",
651 },
652
653 /* sh4:
654 See fmov instructions above for move to/from extended fp registers. */
655
656 /* sh2e */
657 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
658 "FP_OP (n, *, m);",
659 },
660
661 /* sh2e */
662 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
663 "FP_UNARY (n, -);",
664 },
665
666 /* sh4a */
667 { "", "", "fpchg", "1111011111111101",
668 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
669 },
670
671 /* sh4 */
672 { "", "", "frchg", "1111101111111101",
673 "if (FPSCR_PR)",
674 " RAISE_EXCEPTION (SIGILL);",
675 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
676 " RAISE_EXCEPTION (SIGILL);",
677 "else",
678 " SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
679 },
680
681 /* sh4 */
682 { "", "", "fsca", "1111eeee11111101",
683 "if (FPSCR_PR)",
684 " RAISE_EXCEPTION (SIGILL);",
685 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
686 " RAISE_EXCEPTION (SIGILL);",
687 "else",
688 " {",
689 " SET_FR (n, fsca_s (FPUL, &sin));",
690 " SET_FR (n+1, fsca_s (FPUL, &cos));",
691 " }",
692 },
693
694 /* sh4 */
695 { "", "", "fschg", "1111001111111101",
696 "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
697 },
698
699 /* sh3e */
700 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
701 "FP_UNARY (n, sqrt);",
702 },
703
704 /* sh4 */
705 { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
706 "if (FPSCR_PR)",
707 " RAISE_EXCEPTION (SIGILL);",
708 "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
709 " RAISE_EXCEPTION (SIGILL);",
710 "else",
711 " SET_FR (n, fsrra_s (FR (n)));",
712 },
713
714 /* sh2e */
715 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
716 "FP_OP (n, -, m);",
717 },
718
719 /* sh2e */
720 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
721 /* sh4 */
722 "if (FPSCR_PR) {",
723 " if (DR (n) != DR (n)) /* NaN */",
724 " FPUL = 0x80000000;",
725 " else",
726 " FPUL = (int) DR (n);",
727 "}",
728 "else",
729 "if (FR (n) != FR (n)) /* NaN */",
730 " FPUL = 0x80000000;",
731 "else",
732 " FPUL = (int) FR (n);",
733 },
734
735 /* sh4 */
736 { "", "", "ftrv <FV_N>", "1111vv0111111101",
737 "if (FPSCR_PR)",
738 " RAISE_EXCEPTION (SIGILL);",
739 "else",
740 "{",
741 " if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
742 " RAISE_EXCEPTION (SIGILL);",
743 " /* FIXME not implemented. */",
744 " printf (\"ftrv xmtrx, FV%d\\n\", v1);",
745 "}",
746 },
747
748 /* sh2e */
749 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
750 " union",
751 " {",
752 " int i;",
753 " float f;",
754 " } u;",
755 " u.i = FPUL;",
756 " SET_FR (n, u.f);",
757 },
758
759 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
760 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
761 "SET_NIP (PT2H (R[n]));",
762 "cycles += 2;",
763 "Delay_Slot (PC + 2);",
764 },
765
766 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
767 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
768 "PR = PH2T (PC + 4);",
769 "if (~doprofile)",
770 " gotcall (PR, R[n]);",
771 "SET_NIP (PT2H (R[n]));",
772 "cycles += 2;",
773 "Delay_Slot (PC + 2);",
774 },
775 { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
776 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
777 "PR = PH2T (PC + 2);",
778 "if (~doprofile)",
779 " gotcall (PR, R[n]);",
780 "SET_NIP (PT2H (R[n]));",
781 },
782 { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
783 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
784 "PR = PH2T (PC + 2);",
785 "if (~doprofile)",
786 " gotcall (PR, i + TBR);",
787 "SET_NIP (PT2H (i + TBR));",
788 },
789
790 { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
791 "CREG (m) = R[n];",
792 "/* FIXME: user mode */",
793 },
794 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
795 "SET_SR (R[n]);",
796 "/* FIXME: user mode */",
797 },
798 { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
799 "SET_MOD (R[n]);",
800 },
801 { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
802 "if (SR_MD)",
803 " DBR = R[n]; /* priv mode */",
804 "else",
805 " RAISE_EXCEPTION (SIGILL); /* user mode */",
806 },
807 { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
808 "if (SR_MD)",
809 " SGR = R[n]; /* priv mode */",
810 "else",
811 " RAISE_EXCEPTION (SIGILL); /* user mode */",
812 },
813 { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
814 "if (SR_MD)", /* FIXME? */
815 " TBR = R[n]; /* priv mode */",
816 "else",
817 " RAISE_EXCEPTION (SIGILL); /* user mode */",
818 },
819 { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
820 "MA (1);",
821 "CREG (m) = RLAT (R[n]);",
822 "R[n] += 4;",
823 "/* FIXME: user mode */",
824 },
825 { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
826 "MA (1);",
827 "SET_SR (RLAT (R[n]));",
828 "R[n] += 4;",
829 "/* FIXME: user mode */",
830 },
831 { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
832 "MA (1);",
833 "SET_MOD (RLAT (R[n]));",
834 "R[n] += 4;",
835 },
836 { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
837 "if (SR_MD)",
838 "{ /* priv mode */",
839 " MA (1);",
840 " DBR = RLAT (R[n]);",
841 " R[n] += 4;",
842 "}",
843 "else",
844 " RAISE_EXCEPTION (SIGILL); /* user mode */",
845 },
846 { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
847 "if (SR_MD)",
848 "{ /* priv mode */",
849 " MA (1);",
850 " SGR = RLAT (R[n]);",
851 " R[n] += 4;",
852 "}",
853 "else",
854 " RAISE_EXCEPTION (SIGILL); /* user mode */",
855 },
856
857 /* sh-dsp */
858 { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
859 "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
860 },
861 { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
862 "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
863 },
864
865 /* sh4a */
866 { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
867 "SET_RC (R[n]);",
868 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
869 "CHECK_INSN_PTR (insn_ptr);",
870 "RE |= 1;",
871 },
872 { "", "", "ldrc #<imm>", "10001010i8*1....",
873 "SET_RC (i);",
874 "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
875 "CHECK_INSN_PTR (insn_ptr);",
876 "RE |= 1;",
877 },
878
879 { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
880 "SREG (m) = R[n];",
881 },
882 { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
883 "MA (1);",
884 "SREG (m) = RLAT (R[n]);",
885 "R[n] += 4;",
886 },
887 /* sh2e / sh-dsp (lds <REG_N>,DSR) */
888 { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
889 "SET_FPSCR (R[n]);",
890 },
891 /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
892 { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
893 "MA (1);",
894 "SET_FPSCR (RLAT (R[n]));",
895 "R[n] += 4;",
896 },
897
898 { "", "", "ldtlb", "0000000000111000",
899 "/* We don't implement cache or tlb, so this is a noop. */",
900 },
901
902 { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
903 "macl (&R0, memory, n, m);",
904 },
905
906 { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
907 "macw (&R0, memory, n, m, endianw);",
908 },
909
910 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
911 "R[n] = SEXT (i);",
912 },
913 { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
914 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
915 "R[n] = ((i << 24) >> 12) | RIAT (nip);",
916 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
917 },
918 { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
919 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
920 "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
921 "SET_NIP (nip + 2); /* Consume 2 more bytes. */",
922 },
923 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
924 "R[n] = R[m];",
925 },
926
927 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
928 "MA (1);",
929 "R0 = RSBAT (i + GBR);",
930 "L (0);",
931 },
932 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
933 "MA (1);",
934 "R0 = RSBAT (i + R[m]);",
935 "L (0);",
936 },
937 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
938 "MA (1);",
939 "R[n] = RSBAT (R0 + R[m]);",
940 "L (n);",
941 },
942 { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
943 "MA (1);",
944 "R[n] = RSBAT (R[m]);",
945 "R[m] += 1;",
946 "L (n);",
947 },
948 { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
949 "MA (1);",
950 "R[n] -= 1;",
951 "R0 = RSBAT (R[n]);",
952 "L (0);",
953 },
954 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
955 "MA (1);",
956 "WBAT (R[n], R[m]);",
957 },
958 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
959 "MA (1);",
960 "WBAT (i + GBR, R0);",
961 },
962 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
963 "MA (1);",
964 "WBAT (i + R[m], R0);",
965 },
966 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
967 "MA (1);",
968 "WBAT (R[n] + R0, R[m]);",
969 },
970 { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
971 "MA (1);",
972 "R[n] -= 1;",
973 "WBAT (R[n], R[m]);",
974 },
975 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
976 "MA (1);",
977 "WBAT (R[n], R0);",
978 "R[n] += 1;",
979 },
980 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
981 "MA (1);",
982 "R[n] = RSBAT (R[m]);",
983 "L (n);",
984 },
985
986 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
987 "MA (1);",
988 "R0 = RLAT (i + GBR);",
989 "L (0);",
990 },
991 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
992 "MA (1);",
993 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
994 "L (n);",
995 },
996 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
997 "MA (1);",
998 "R[n] = RLAT (i + R[m]);",
999 "L (n);",
1000 },
1001 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1002 "MA (1);",
1003 "R[n] = RLAT (R0 + R[m]);",
1004 "L (n);",
1005 },
1006 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1007 "MA (1);",
1008 "R[n] = RLAT (R[m]);",
1009 "R[m] += 4;",
1010 "L (n);",
1011 },
1012 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1013 "MA (1);",
1014 "R[n] -= 4;",
1015 "R0 = RLAT (R[n]);",
1016 "L (0);",
1017 },
1018 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1019 "MA (1);",
1020 "R[n] = RLAT (R[m]);",
1021 "L (n);",
1022 },
1023 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1024 "MA (1);",
1025 "WLAT (i + GBR, R0);",
1026 },
1027 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1028 "MA (1);",
1029 "WLAT (i + R[n], R[m]);",
1030 },
1031 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1032 "MA (1);",
1033 "WLAT (R0 + R[n], R[m]);",
1034 },
1035 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1036 "MA (1) ;",
1037 "R[n] -= 4;",
1038 "WLAT (R[n], R[m]);",
1039 },
1040 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1041 "MA (1) ;",
1042 "WLAT (R[n], R0);",
1043 "R[n] += 4;",
1044 },
1045 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1046 "MA (1);",
1047 "WLAT (R[n], R[m]);",
1048 },
1049
1050 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1051 "MA (1);",
1052 "R0 = RSWAT (i + GBR);",
1053 "L (0);",
1054 },
1055 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1056 "MA (1);",
1057 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1058 "L (n);",
1059 },
1060 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1061 "MA (1);",
1062 "R0 = RSWAT (i + R[m]);",
1063 "L (0);",
1064 },
1065 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1066 "MA (1);",
1067 "R[n] = RSWAT (R0 + R[m]);",
1068 "L (n);",
1069 },
1070 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1071 "MA (1);",
1072 "R[n] = RSWAT (R[m]);",
1073 "R[m] += 2;",
1074 "L (n);",
1075 },
1076 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1077 "MA (1);",
1078 "R[n] -= 2;",
1079 "R0 = RSWAT (R[n]);",
1080 "L (0);",
1081 },
1082 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1083 "MA (1);",
1084 "R[n] = RSWAT (R[m]);",
1085 "L (n);",
1086 },
1087 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1088 "MA (1);",
1089 "WWAT (i + GBR, R0);",
1090 },
1091 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1092 "MA (1);",
1093 "WWAT (i + R[m], R0);",
1094 },
1095 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1096 "MA (1);",
1097 "WWAT (R0 + R[n], R[m]);",
1098 },
1099 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1100 "MA (1);",
1101 "R[n] -= 2;",
1102 "WWAT (R[n], R[m]);",
1103 },
1104 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1105 "MA (1);",
1106 "WWAT (R[n], R0);",
1107 "R[n] += 2;",
1108 },
1109 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1110 "MA (1);",
1111 "WWAT (R[n], R[m]);",
1112 },
1113
1114 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1115 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1116 },
1117
1118 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1119 "/* We don't simulate cache, so this insn is identical to mov. */",
1120 "MA (1);",
1121 "WLAT (R[n], R[0]);",
1122 },
1123
1124 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1125 "/* LDST -> T */",
1126 "SET_SR_T (LDST);",
1127 "/* if (T) R0 -> (Rn) */",
1128 "if (T)",
1129 " WLAT (R[n], R[0]);",
1130 "/* 0 -> LDST */",
1131 "SET_LDST (0);",
1132 },
1133
1134 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1135 "/* 1 -> LDST */",
1136 "SET_LDST (1);",
1137 "/* (Rn) -> R0 */",
1138 "R[0] = RLAT (R[n]);",
1139 "/* if (interrupt/exception) 0 -> LDST */",
1140 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1141 },
1142
1143 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1144 "R[n] = T;",
1145 },
1146 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1147 "R[n] = (T == 0);",
1148 },
1149 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1150 "int regn = R[n];",
1151 "int e = target_little_endian ? 3 : 0;",
1152 "MA (1);",
1153 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1154 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1155 "L (0);",
1156 },
1157 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1158 "int regn = R[n];",
1159 "int e = target_little_endian ? 3 : 0;",
1160 "MA (1);",
1161 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1162 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1163 "R[n] += 4;",
1164 "L (0);",
1165 },
1166 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1167 "MACL = ((int) R[n]) * ((int) R[m]);",
1168 },
1169#if 0 /* FIXME: The above cast to int is not really portable.
1170 It should be replaced by a SEXT32 macro. */
1171 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1172 "MACL = R[n] * R[m];",
1173 },
1174#endif
1175
1176 /* muls.w - see muls */
1177 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1178 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1179 },
1180
1181 /* mulu.w - see mulu */
1182 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1183 "MACL = (((unsigned int) (unsigned short) R[n])",
1184 " * ((unsigned int) (unsigned short) R[m]));",
1185 },
1186
1187 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1188 "R[n] = - R[m];",
1189 },
1190
1191 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1192 "ult = -T;",
1193 "SET_SR_T (ult > 0);",
1194 "R[n] = ult - R[m];",
1195 "SET_SR_T (T || (R[n] > ult));",
1196 },
1197
1198 { "", "", "nop", "0000000000001001",
1199 "/* nop */",
1200 },
1201
1202 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1203 "R[n] = ~R[m];",
1204 },
1205
1206 /* sh4a */
1207 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1208 "/* Except for the effect on the cache - which is not simulated -",
1209 " this is like a nop. */",
1210 },
1211
1212 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1213 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1214 "/* FIXME: Cache not implemented */",
1215 },
1216
1217 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1218 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1219 "/* FIXME: Cache not implemented */",
1220 },
1221
1222 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1223 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1224 "/* FIXME: Cache not implemented */",
1225 },
1226
1227 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1228 "R0 |= i;",
1229 },
1230 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1231 "R[n] |= R[m];",
1232 },
1233 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1234 "MA (1);",
1235 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1236 },
1237
1238 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1239 "/* Except for the effect on the cache - which is not simulated -",
1240 " this is like a nop. */",
1241 },
1242
1243 /* sh4a */
1244 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1245 "/* Except for the effect on the cache - which is not simulated -",
1246 " this is like a nop. */",
1247 },
1248
1249 /* sh4a */
1250 { "", "", "synco", "0000000010101011",
1251 "/* Except for the effect on the pipeline - which is not simulated -",
1252 " this is like a nop. */",
1253 },
1254
1255 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1256 "ult = R[n] < 0;",
1257 "R[n] = (R[n] << 1) | T;",
1258 "SET_SR_T (ult);",
1259 },
1260
1261 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1262 "ult = R[n] & 1;",
1263 "R[n] = (UR[n] >> 1) | (T << 31);",
1264 "SET_SR_T (ult);",
1265 },
1266
1267 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1268 "SET_SR_T (R[n] < 0);",
1269 "R[n] <<= 1;",
1270 "R[n] |= T;",
1271 },
1272
1273 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1274 "SET_SR_T (R[n] & 1);",
1275 "R[n] = UR[n] >> 1;",
1276 "R[n] |= (T << 31);",
1277 },
1278
1279 { "", "", "rte", "0000000000101011",
1280#if 0
1281 /* SH-[12] */
1282 "int tmp = PC;",
1283 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1284 "R[15] += 4;",
1285 "SET_SR (RLAT (R[15]) & 0x3f3);",
1286 "R[15] += 4;",
1287 "Delay_Slot (PC + 2);",
1288#else
1289 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1290 "SET_SR (SSR);",
1291 "SET_NIP (PT2H (SPC));",
1292 "cycles += 2;",
1293 "Delay_Slot (PC + 2);",
1294#endif
1295 },
1296
1297 { "", "", "rts", "0000000000001011",
1298 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1299 "SET_NIP (PT2H (PR));",
1300 "cycles += 2;",
1301 "Delay_Slot (PC + 2);",
1302 },
1303 { "", "", "rts/n", "0000000001101011",
1304 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1305 "SET_NIP (PT2H (PR));",
1306 },
1307 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1308 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1309 "R0 = R[n];",
1310 "L (0);",
1311 "SET_NIP (PT2H (PR));",
1312 },
1313
1314 /* sh4a */
1315 { "", "", "setdmx", "0000000010011000",
1316 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1317 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1318 },
1319
1320 /* sh4a */
1321 { "", "", "setdmy", "0000000011001000",
1322 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1323 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1324 },
1325
1326 /* sh-dsp */
1327 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1328 "SET_RC (R[n]);",
1329 },
1330 { "", "", "setrc #<imm>", "10000010i8*1....",
1331 /* It would be more realistic to let loop_start point to some static
1332 memory that contains an illegal opcode and then give a bus error when
1333 the loop is eventually encountered, but it seems not only simpler,
1334 but also more debugging-friendly to just catch the failure here. */
1335 "if (BUSERROR (RS | RE, maskw))",
1336 " RAISE_EXCEPTION (SIGILL);",
1337 "else {",
1338 " SET_RC (i);",
1339 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1340 " CHECK_INSN_PTR (insn_ptr);",
1341 "}",
1342 },
1343
1344 { "", "", "sets", "0000000001011000",
1345 "SET_SR_S (1);",
1346 },
1347
1348 { "", "", "sett", "0000000000011000",
1349 "SET_SR_T (1);",
1350 },
1351
1352 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1353 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1354 },
1355
1356 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1357 "SET_SR_T (R[n] < 0);",
1358 "R[n] <<= 1;",
1359 },
1360
1361 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1362 "SET_SR_T (R[n] & 1);",
1363 "R[n] = R[n] >> 1;",
1364 },
1365
1366 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1367 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1368 },
1369
1370 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1371 "SET_SR_T (R[n] < 0);",
1372 "R[n] <<= 1;",
1373 },
1374
1375 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1376 "R[n] <<= 2;",
1377 },
1378 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1379 "R[n] <<= 8;",
1380 },
1381 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1382 "R[n] <<= 16;",
1383 },
1384
1385 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1386 "SET_SR_T (R[n] & 1);",
1387 "R[n] = UR[n] >> 1;",
1388 },
1389
1390 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1391 "R[n] = UR[n] >> 2;",
1392 },
1393 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1394 "R[n] = UR[n] >> 8;",
1395 },
1396 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1397 "R[n] = UR[n] >> 16;",
1398 },
1399
1400 { "", "", "sleep", "0000000000011011",
1401 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1402 },
1403
1404 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1405 "R[n] = CREG (m);",
1406 },
1407
1408 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1409 "if (SR_MD)",
1410 " R[n] = SGR; /* priv mode */",
1411 "else",
1412 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1413 },
1414 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1415 "if (SR_MD)",
1416 " R[n] = DBR; /* priv mode */",
1417 "else",
1418 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1419 },
1420 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1421 "if (SR_MD)", /* FIXME? */
1422 " R[n] = TBR; /* priv mode */",
1423 "else",
1424 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1425 },
1426 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1427 "MA (1);",
1428 "R[n] -= 4;",
1429 "WLAT (R[n], CREG (m));",
1430 },
1431 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1432 "if (SR_MD)",
1433 "{ /* priv mode */",
1434 " MA (1);",
1435 " R[n] -= 4;",
1436 " WLAT (R[n], SGR);",
1437 "}",
1438 "else",
1439 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1440 },
1441 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1442 "if (SR_MD)",
1443 "{ /* priv mode */",
1444 " MA (1);",
1445 " R[n] -= 4;",
1446 " WLAT (R[n], DBR);",
1447 "}",
1448 "else",
1449 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1450 },
1451
1452 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1453 "R[n] = SREG (m);",
1454 },
1455 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1456 "MA (1);",
1457 "R[n] -= 4;",
1458 "WLAT (R[n], SREG (m));",
1459 },
1460
1461 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1462 "R[n] -= R[m];",
1463 },
1464
1465 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1466 "ult = R[n] - T;",
1467 "SET_SR_T (ult > R[n]);",
1468 "R[n] = ult - R[m];",
1469 "SET_SR_T (T || (R[n] > ult));",
1470 },
1471
1472 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1473 "ult = R[n] - R[m];",
1474 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1475 "R[n] = ult;",
1476 },
1477
1478 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1479 "R[n] = ((R[m] & 0xffff0000)",
1480 " | ((R[m] << 8) & 0xff00)",
1481 " | ((R[m] >> 8) & 0x00ff));",
1482 },
1483 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1484 "R[n] = (((R[m] << 16) & 0xffff0000)",
1485 " | ((R[m] >> 16) & 0x00ffff));",
1486 },
1487
1488 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1489 "MA (1);",
1490 "ult = RBAT (R[n]);",
1491 "SET_SR_T (ult == 0);",
1492 "WBAT (R[n],ult|0x80);",
1493 },
1494
1495 { "0", "", "trapa #<imm>", "11000011i8*1....",
1496 "long imm = 0xff & i;",
1497 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1498 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1499 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1500#if 0
1501 "else {",
1502 /* SH-[12] */
1503 " R[15] -= 4;",
1504 " WLAT (R[15], GET_SR ());",
1505 " R[15] -= 4;",
1506 " WLAT (R[15], PH2T (PC + 2));",
1507#else
1508 "else if (!SR_BL) {",
1509 " SSR = GET_SR ();",
1510 " SPC = PH2T (PC + 2);",
1511 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1512 " /* FIXME: EXPEVT = 0x00000160; */",
1513#endif
1514 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1515 "}",
1516 },
1517
1518 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1519 "SET_SR_T ((R[n] & R[m]) == 0);",
1520 },
1521 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1522 "SET_SR_T ((R0 & i) == 0);",
1523 },
1524 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1525 "MA (1);",
1526 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1527 },
1528
1529 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1530 "R0 ^= i;",
1531 },
1532 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1533 "R[n] ^= R[m];",
1534 },
1535 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1536 "MA (1);",
1537 "ult = RBAT (GBR+R0);",
1538 "ult ^= i;",
1539 "WBAT (GBR + R0, ult);",
1540 },
1541
1542 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1543 "R[n] = (((R[n] >> 16) & 0xffff)",
1544 " | ((R[m] << 16) & 0xffff0000));",
1545 },
1546
1547#if 0
1548 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1549 "divl (0, R[n], R[m]);",
1550 },
1551 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1552 "divl (0, R[n], R[m]);",
1553 },
1554#endif
1555
1556 {0, 0}};
1557
1558op movsxy_tab[] =
1559{
1560/* If this is disabled, the simulator speeds up by about 12% on a
1561 450 MHz PIII - 9% with ACE_FAST.
1562 Maybe we should have separate simulator loops? */
1563#if 1
1564 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1565 "MA (1);",
1566 "R[n] -= 2;",
1567 "DSP_R (m) = RSWAT (R[n]) << 16;",
1568 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1569 },
1570 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1571 "MA (1);",
1572 "DSP_R (m) = RSWAT (R[n]) << 16;",
1573 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1574 },
1575 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1576 "MA (1);",
1577 "DSP_R (m) = RSWAT (R[n]) << 16;",
1578 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1579 "R[n] += 2;",
1580 },
1581 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1582 "MA (1);",
1583 "DSP_R (m) = RSWAT (R[n]) << 16;",
1584 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1585 "R[n] += R[8];",
1586 },
1587 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1588 "MA (1);",
1589 "R[n] -= 2;",
1590 "DSP_R (m) = RSWAT (R[n]);",
1591 },
1592 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1593 "MA (1);",
1594 "DSP_R (m) = RSWAT (R[n]);",
1595 },
1596 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1597 "MA (1);",
1598 "DSP_R (m) = RSWAT (R[n]);",
1599 "R[n] += 2;",
1600 },
1601 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1602 "MA (1);",
1603 "DSP_R (m) = RSWAT (R[n]);",
1604 "R[n] += R[8];",
1605 },
1606 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1607 "MA (1);",
1608 "R[n] -= 2;",
1609 "WWAT (R[n], DSP_R (m) >> 16);",
1610 },
1611 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1612 "MA (1);",
1613 "WWAT (R[n], DSP_R (m) >> 16);",
1614 },
1615 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1616 "MA (1);",
1617 "WWAT (R[n], DSP_R (m) >> 16);",
1618 "R[n] += 2;",
1619 },
1620 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1621 "MA (1);",
1622 "WWAT (R[n], DSP_R (m) >> 16);",
1623 "R[n] += R[8];",
1624 },
1625 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1626 "MA (1);",
1627 "R[n] -= 2;",
1628 "WWAT (R[n], SEXT (DSP_R (m)));",
1629 },
1630 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1631 "MA (1);",
1632 "WWAT (R[n], SEXT (DSP_R (m)));",
1633 },
1634 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1635 "MA (1);",
1636 "WWAT (R[n], SEXT (DSP_R (m)));",
1637 "R[n] += 2;",
1638 },
1639 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1640 "MA (1);",
1641 "WWAT (R[n], SEXT (DSP_R (m)));",
1642 "R[n] += R[8];",
1643 },
1644 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1645 "MA (1);",
1646 "R[n] -= 4;",
1647 "DSP_R (m) = RLAT (R[n]);",
1648 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1649 },
1650 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1651 "MA (1);",
1652 "DSP_R (m) = RLAT (R[n]);",
1653 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1654 },
1655 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1656 "MA (1);",
1657 "DSP_R (m) = RLAT (R[n]);",
1658 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1659 "R[n] += 4;",
1660 },
1661 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1662 "MA (1);",
1663 "DSP_R (m) = RLAT (R[n]);",
1664 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1665 "R[n] += R[8];",
1666 },
1667 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1668 "MA (1);",
1669 "R[n] -= 4;",
1670 "WLAT (R[n], DSP_R (m));",
1671 },
1672 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1673 "MA (1);",
1674 "WLAT (R[n], DSP_R (m));",
1675 },
1676 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1677 "MA (1);",
1678 "WLAT (R[n], DSP_R (m));",
1679 "R[n] += 4;",
1680 },
1681 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1682 "MA (1);",
1683 "WLAT (R[n], DSP_R (m));",
1684 "R[n] += R[8];",
1685 },
1686 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1687 "MA (1);",
1688 "R[n] -= 4;",
1689 "WLAT (R[n], SEXT (DSP_R (m)));",
1690 },
1691 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1692 "MA (1);",
1693 "WLAT (R[n], SEXT (DSP_R (m)));",
1694 },
1695 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1696 "MA (1);",
1697 "WLAT (R[n], SEXT (DSP_R (m)));",
1698 "R[n] += 4;",
1699 },
1700 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1701 "MA (1);",
1702 "WLAT (R[n], SEXT (DSP_R (m)));",
1703 "R[n] += R[8];",
1704 },
1705 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1706 "DSP_R (m) = RSWAT (R[n]) << 16;",
1707 "if (iword & 3)",
1708 " {",
1709 " iword &= 0xfd53; goto top;",
1710 " }",
1711 },
1712 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1713 "DSP_R (m) = RLAT (R[n]);",
1714 },
1715 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1716 "DSP_R (m) = RSWAT (R[n]) << 16;",
1717 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1718 "if (iword & 3)",
1719 " {",
1720 " iword &= 0xfd53; goto top;",
1721 " }",
1722 },
1723 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1724 "DSP_R (m) = RLAT (R[n]);",
1725 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1726 },
1727 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1728 "DSP_R (m) = RSWAT (R[n]) << 16;",
1729 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1730 "if (iword & 3)",
1731 " {",
1732 " iword &= 0xfd53; goto top;",
1733 " }",
1734 },
1735 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1736 "DSP_R (m) = RLAT (R[n]);",
1737 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1738 },
1739 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1740 "WWAT (R[n], DSP_R (m) >> 16);",
1741 "if (iword & 3)",
1742 " {",
1743 " iword &= 0xfd53; goto top;",
1744 " }",
1745 },
1746 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1747 "WLAT (R[n], DSP_R (m));",
1748 },
1749 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1750 "WWAT (R[n], DSP_R (m) >> 16);",
1751 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1752 "if (iword & 3)",
1753 " {",
1754 " iword &= 0xfd53; goto top;",
1755 " }",
1756 },
1757 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1758 "WLAT (R[n], DSP_R (m));",
1759 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1760 },
1761 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1762 "WWAT (R[n], DSP_R (m) >> 16);",
1763 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1764 "if (iword & 3)",
1765 " {",
1766 " iword &= 0xfd53; goto top;",
1767 " }",
1768 },
1769 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1770 "WLAT (R[n], DSP_R (m));",
1771 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1772 },
1773 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1774 "DSP_R (m) = RSWAT (R[n]) << 16;",
1775 },
1776 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1777 "DSP_R (m) = RSWAT (R[n]) << 16;",
1778 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1779 },
1780 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1781 "DSP_R (m) = RSWAT (R[n]) << 16;",
1782 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1783 },
1784 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1785 "WWAT (R[n], DSP_R (m) >> 16);",
1786 },
1787 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1788 "WWAT (R[n], DSP_R (m) >> 16);",
1789 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1790 },
1791 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1792 "WWAT (R[n], DSP_R (m) >> 16);",
1793 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1794 },
1795 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1796 "DSP_R (m) = RLAT (R[n]);",
1797 },
1798 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1799 "DSP_R (m) = RLAT (R[n]);",
1800 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1801 },
1802 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1803 "DSP_R (m) = RLAT (R[n]);",
1804 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1805 },
1806 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1807 "WLAT (R[n], DSP_R (m));",
1808 },
1809 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1810 "WLAT (R[n], DSP_R (m));",
1811 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1812 },
1813 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1814 "WLAT (R[n], DSP_R (m));",
1815 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1816 },
1817 { "", "", "nopx nopy", "1111000000000000",
1818 "/* nop */",
1819 },
1820 { "", "", "ppi", "1111100000000000",
1821 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1822 "ppi_insn (RIAT (nip));",
1823 "SET_NIP (nip + 2);",
1824 "iword &= 0xf7ff; goto top;",
1825 },
1826#endif
1827 {0, 0}};
1828
1829op ppi_tab[] =
1830{
1831 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1832 "int Sz = DSP_R (z) & 0xffff0000;",
1833 "",
1834 "if (i <= 16)",
1835 " res = Sz << i;",
1836 "else if (i >= 128 - 16)",
1837 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1838 "else",
1839 " {",
1840 " RAISE_EXCEPTION (SIGILL);",
1841 " return;",
1842 " }",
1843 "res &= 0xffff0000;",
1844 "res_grd = 0;",
1845 "goto logical;",
1846 },
1847 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1848 "int Sz = DSP_R (z);",
1849 "int Sz_grd = GET_DSP_GRD (z);",
1850 "",
1851 "if (i <= 32)",
1852 " {",
1853 " if (i == 32)",
1854 " {",
1855 " res = 0;",
1856 " res_grd = Sz;",
1857 " }",
1858 " else",
1859 " {",
1860 " res = Sz << i;",
1861 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1862 " }",
1863 " res_grd = SEXT (res_grd);",
1864 " carry = res_grd & 1;",
1865 " }",
1866 "else if (i >= 96)",
1867 " {",
1868 " i = 128 - i;",
1869 " if (i == 32)",
1870 " {",
1871 " res_grd = SIGN32 (Sz_grd);",
1872 " res = Sz_grd;",
1873 " }",
1874 " else",
1875 " {",
1876 " res = Sz >> i | Sz_grd << 32 - i;",
1877 " res_grd = Sz_grd >> i;",
1878 " }",
1879 " carry = Sz >> (i - 1) & 1;",
1880 " }",
1881 "else",
1882 " {",
1883 " RAISE_EXCEPTION (SIGILL);",
1884 " return;",
1885 " }",
1886 "COMPUTE_OVERFLOW;",
1887 "greater_equal = 0;",
1888 },
1889 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1890 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1891 "if (res == 0x80000000)",
1892 " res = 0x7fffffff;",
1893 "DSP_R (g) = res;",
1894 "DSP_GRD (g) = SIGN32 (res);",
1895 "return;",
1896 },
1897 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1898 "int Sx = DSP_R (x);",
1899 "int Sx_grd = GET_DSP_GRD (x);",
1900 "int Sy = DSP_R (y);",
1901 "int Sy_grd = SIGN32 (Sy);",
1902 "",
1903 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1904 "if (res == 0x80000000)",
1905 " res = 0x7fffffff;",
1906 "DSP_R (g) = res;",
1907 "DSP_GRD (g) = SIGN32 (res);",
1908 "",
1909 "z = u;",
1910 "res = Sx - Sy;",
1911 "carry = (unsigned) res > (unsigned) Sx;",
1912 "res_grd = Sx_grd - Sy_grd - carry;",
1913 "COMPUTE_OVERFLOW;",
1914 "ADD_SUB_GE;",
1915 },
1916 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1917 "int Sx = DSP_R (x);",
1918 "int Sx_grd = GET_DSP_GRD (x);",
1919 "int Sy = DSP_R (y);",
1920 "int Sy_grd = SIGN32 (Sy);",
1921 "",
1922 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1923 "if (res == 0x80000000)",
1924 " res = 0x7fffffff;",
1925 "DSP_R (g) = res;",
1926 "DSP_GRD (g) = SIGN32 (res);",
1927 "",
1928 "z = u;",
1929 "res = Sx + Sy;",
1930 "carry = (unsigned) res < (unsigned) Sx;",
1931 "res_grd = Sx_grd + Sy_grd + carry;",
1932 "COMPUTE_OVERFLOW;",
1933 },
1934 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1935 "int Sx = DSP_R (x);",
1936 "int Sx_grd = GET_DSP_GRD (x);",
1937 "int Sy = DSP_R (y);",
1938 "int Sy_grd = SIGN32 (Sy);",
1939 "",
1940 "res = Sx - Sy - (DSR & 1);",
1941 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1942 "res_grd = Sx_grd + Sy_grd + carry;",
1943 "COMPUTE_OVERFLOW;",
1944 "ADD_SUB_GE;",
1945 "DSR &= ~0xf1;\n",
1946 "if (res || res_grd)\n",
1947 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1948 "else\n",
1949 " DSR |= DSR_MASK_Z | overflow;\n",
1950 "DSR |= carry;\n",
1951 "goto assign_z;\n",
1952 },
1953 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1954 "int Sx = DSP_R (x);",
1955 "int Sx_grd = GET_DSP_GRD (x);",
1956 "int Sy = DSP_R (y);",
1957 "int Sy_grd = SIGN32 (Sy);",
1958 "",
1959 "res = Sx + Sy + (DSR & 1);",
1960 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1961 "res_grd = Sx_grd + Sy_grd + carry;",
1962 "COMPUTE_OVERFLOW;",
1963 "ADD_SUB_GE;",
1964 "DSR &= ~0xf1;\n",
1965 "if (res || res_grd)\n",
1966 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1967 "else\n",
1968 " DSR |= DSR_MASK_Z | overflow;\n",
1969 "DSR |= carry;\n",
1970 "goto assign_z;\n",
1971 },
1972 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1973 "int Sx = DSP_R (x);",
1974 "int Sx_grd = GET_DSP_GRD (x);",
1975 "int Sy = DSP_R (y);",
1976 "int Sy_grd = SIGN32 (Sy);",
1977 "",
1978 "z = 17; /* Ignore result. */",
1979 "res = Sx - Sy;",
1980 "carry = (unsigned) res > (unsigned) Sx;",
1981 "res_grd = Sx_grd - Sy_grd - carry;",
1982 "COMPUTE_OVERFLOW;",
1983 "ADD_SUB_GE;",
1984 },
1985 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1986 },
1987 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1988 },
1989 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
1990 "/* FIXME: duplicate code pabs. */",
1991 "res = DSP_R (x);",
1992 "res_grd = GET_DSP_GRD (x);",
1993 "if (res >= 0)",
1994 " carry = 0;",
1995 "else",
1996 " {",
1997 " res = -res;",
1998 " carry = (res != 0); /* The manual has a bug here. */",
1999 " res_grd = -res_grd - carry;",
2000 " }",
2001 "COMPUTE_OVERFLOW;",
2002 "/* ??? The re-computing of overflow after",
2003 " saturation processing is specific to pabs. */",
2004 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2005 "ADD_SUB_GE;",
2006 },
2007 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2008 "res = DSP_R (x);",
2009 "res_grd = GET_DSP_GRD (x);",
2010 "if (res >= 0)",
2011 " carry = 0;",
2012 "else",
2013 " {",
2014 " res = -res;",
2015 " carry = (res != 0); /* The manual has a bug here. */",
2016 " res_grd = -res_grd - carry;",
2017 " }",
2018 "COMPUTE_OVERFLOW;",
2019 "/* ??? The re-computing of overflow after",
2020 " saturation processing is specific to pabs. */",
2021 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2022 "ADD_SUB_GE;",
2023 },
2024
2025 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2026 "/* FIXME: duplicate code prnd. */",
2027 "int Sx = DSP_R (x);",
2028 "int Sx_grd = GET_DSP_GRD (x);",
2029 "",
2030 "res = (Sx + 0x8000) & 0xffff0000;",
2031 "carry = (unsigned) res < (unsigned) Sx;",
2032 "res_grd = Sx_grd + carry;",
2033 "COMPUTE_OVERFLOW;",
2034 "ADD_SUB_GE;",
2035 },
2036 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2037 "int Sx = DSP_R (x);",
2038 "int Sx_grd = GET_DSP_GRD (x);",
2039 "",
2040 "res = (Sx + 0x8000) & 0xffff0000;",
2041 "carry = (unsigned) res < (unsigned) Sx;",
2042 "res_grd = Sx_grd + carry;",
2043 "COMPUTE_OVERFLOW;",
2044 "ADD_SUB_GE;",
2045 },
2046
2047 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2048 "/* FIXME: duplicate code pabs. */",
2049 "res = DSP_R (y);",
2050 "res_grd = 0;",
2051 "overflow = 0;",
2052 "greater_equal = DSR_MASK_G;",
2053 "if (res >= 0)",
2054 " carry = 0;",
2055 "else",
2056 " {",
2057 " res = -res;",
2058 " carry = 1;",
2059 " if (res < 0)",
2060 " {",
2061 " if (S)",
2062 " res = 0x7fffffff;",
2063 " else",
2064 " {",
2065 " overflow = DSR_MASK_V;",
2066 " greater_equal = 0;",
2067 " }",
2068 " }",
2069 " }",
2070 },
2071 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2072 "res = DSP_R (y);",
2073 "res_grd = 0;",
2074 "overflow = 0;",
2075 "greater_equal = DSR_MASK_G;",
2076 "if (res >= 0)",
2077 " carry = 0;",
2078 "else",
2079 " {",
2080 " res = -res;",
2081 " carry = 1;",
2082 " if (res < 0)",
2083 " {",
2084 " if (S)",
2085 " res = 0x7fffffff;",
2086 " else",
2087 " {",
2088 " overflow = DSR_MASK_V;",
2089 " greater_equal = 0;",
2090 " }",
2091 " }",
2092 " }",
2093 },
2094 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2095 "/* FIXME: duplicate code prnd. */",
2096 "int Sy = DSP_R (y);",
2097 "int Sy_grd = SIGN32 (Sy);",
2098 "",
2099 "res = (Sy + 0x8000) & 0xffff0000;",
2100 "carry = (unsigned) res < (unsigned) Sy;",
2101 "res_grd = Sy_grd + carry;",
2102 "COMPUTE_OVERFLOW;",
2103 "ADD_SUB_GE;",
2104 },
2105 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2106 "int Sy = DSP_R (y);",
2107 "int Sy_grd = SIGN32 (Sy);",
2108 "",
2109 "res = (Sy + 0x8000) & 0xffff0000;",
2110 "carry = (unsigned) res < (unsigned) Sy;",
2111 "res_grd = Sy_grd + carry;",
2112 "COMPUTE_OVERFLOW;",
2113 "ADD_SUB_GE;",
2114 },
2115 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2116 "int Sx = DSP_R (x) & 0xffff0000;",
2117 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2118 "",
2119 "if (Sy <= 16)",
2120 " res = Sx << Sy;",
2121 "else if (Sy >= 128 - 16)",
2122 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2123 "else",
2124 " {",
2125 " RAISE_EXCEPTION (SIGILL);",
2126 " return;",
2127 " }",
2128 "goto cond_logical;",
2129 },
2130 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2131 "int Sx = DSP_R (x);",
2132 "int Sx_grd = GET_DSP_GRD (x);",
2133 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2134 "",
2135 "if (Sy <= 32)",
2136 " {",
2137 " if (Sy == 32)",
2138 " {",
2139 " res = 0;",
2140 " res_grd = Sx;",
2141 " }",
2142 " else",
2143 " {",
2144 " res = Sx << Sy;",
2145 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2146 " }",
2147 " res_grd = SEXT (res_grd);",
2148 " carry = res_grd & 1;",
2149 " }",
2150 "else if (Sy >= 96)",
2151 " {",
2152 " Sy = 128 - Sy;",
2153 " if (Sy == 32)",
2154 " {",
2155 " res_grd = SIGN32 (Sx_grd);",
2156 " res = Sx_grd;",
2157 " }",
2158 " else",
2159 " {",
2160 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
2161 " res_grd = Sx_grd >> Sy;",
2162 " }",
2163 " carry = Sx >> (Sy - 1) & 1;",
2164 " }",
2165 "else",
2166 " {",
2167 " RAISE_EXCEPTION (SIGILL);",
2168 " return;",
2169 " }",
2170 "COMPUTE_OVERFLOW;",
2171 "greater_equal = 0;",
2172 },
2173 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2174 "int Sx = DSP_R (x);",
2175 "int Sx_grd = GET_DSP_GRD (x);",
2176 "int Sy = DSP_R (y);",
2177 "int Sy_grd = SIGN32 (Sy);",
2178 "",
2179 "res = Sx - Sy;",
2180 "carry = (unsigned) res > (unsigned) Sx;",
2181 "res_grd = Sx_grd - Sy_grd - carry;",
2182 "COMPUTE_OVERFLOW;",
2183 "ADD_SUB_GE;",
2184 },
2185 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2186 "int Sx = DSP_R (x);",
2187 "int Sx_grd = GET_DSP_GRD (x);",
2188 "int Sy = DSP_R (y);",
2189 "int Sy_grd = SIGN32 (Sy);",
2190 "",
2191 "res = Sy - Sx;",
2192 "carry = (unsigned) res > (unsigned) Sy;",
2193 "res_grd = Sy_grd - Sx_grd - carry;",
2194 "COMPUTE_OVERFLOW;",
2195 "ADD_SUB_GE;",
2196 },
2197 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2198 "int Sx = DSP_R (x);",
2199 "int Sx_grd = GET_DSP_GRD (x);",
2200 "int Sy = DSP_R (y);",
2201 "int Sy_grd = SIGN32 (Sy);",
2202 "",
2203 "res = Sx + Sy;",
2204 "carry = (unsigned) res < (unsigned) Sx;",
2205 "res_grd = Sx_grd + Sy_grd + carry;",
2206 "COMPUTE_OVERFLOW;",
2207 "ADD_SUB_GE;",
2208 },
2209 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2210 "res = DSP_R (x) & DSP_R (y);",
2211 "cond_logical:",
2212 "res &= 0xffff0000;",
2213 "res_grd = 0;",
2214 "if (iword & 0x200)\n",
2215 " goto assign_z;\n",
2216 "logical:",
2217 "carry = 0;",
2218 "overflow = 0;",
2219 "greater_equal = 0;",
2220 "DSR &= ~0xf1;\n",
2221 "if (res)\n",
2222 " DSR |= res >> 26 & DSR_MASK_N;\n",
2223 "else\n",
2224 " DSR |= DSR_MASK_Z;\n",
2225 "goto assign_dc;\n",
2226 },
2227 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2228 "res = DSP_R (x) ^ DSP_R (y);",
2229 "goto cond_logical;",
2230 },
2231 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2232 "res = DSP_R (x) | DSP_R (y);",
2233 "goto cond_logical;",
2234 },
2235 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..zzzz",
2236 "int Sx = DSP_R (x);",
2237 "int Sx_grd = GET_DSP_GRD (x);",
2238 "",
2239 "res = Sx - 0x10000;",
2240 "carry = res > Sx;",
2241 "res_grd = Sx_grd - carry;",
2242 "COMPUTE_OVERFLOW;",
2243 "ADD_SUB_GE;",
2244 "res &= 0xffff0000;",
2245 },
2246 { "","", "(if cc) pinc Sx,Dz", "100110ccxx..zzzz",
2247 "int Sx = DSP_R (x);",
2248 "int Sx_grd = GET_DSP_GRD (x);",
2249 "",
2250 "res = Sx + 0x10000;",
2251 "carry = res < Sx;",
2252 "res_grd = Sx_grd + carry;",
2253 "COMPUTE_OVERFLOW;",
2254 "ADD_SUB_GE;",
2255 "res &= 0xffff0000;",
2256 },
2257 { "","", "(if cc) pdec Sy,Dz", "101010cc..yyzzzz",
2258 "int Sy = DSP_R (y);",
2259 "int Sy_grd = SIGN32 (Sy);",
2260 "",
2261 "res = Sy - 0x10000;",
2262 "carry = res > Sy;",
2263 "res_grd = Sy_grd - carry;",
2264 "COMPUTE_OVERFLOW;",
2265 "ADD_SUB_GE;",
2266 "res &= 0xffff0000;",
2267 },
2268 { "","", "(if cc) pinc Sy,Dz", "101110cc..yyzzzz",
2269 "int Sy = DSP_R (y);",
2270 "int Sy_grd = SIGN32 (Sy);",
2271 "",
2272 "res = Sy + 0x10000;",
2273 "carry = res < Sy;",
2274 "res_grd = Sy_grd + carry;",
2275 "COMPUTE_OVERFLOW;",
2276 "ADD_SUB_GE;",
2277 "res &= 0xffff0000;",
2278 },
2279 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2280 "res = 0;",
2281 "res_grd = 0;",
2282 "carry = 0;",
2283 "overflow = 0;",
2284 "greater_equal = 1;",
2285 },
2286 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2287 "/* Do multiply. */",
2288 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2289 "if (res == 0x80000000)",
2290 " res = 0x7fffffff;",
2291 "DSP_R (g) = res;",
2292 "DSP_GRD (g) = SIGN32 (res);",
2293 "/* FIXME: update DSR based on results of multiply! */",
2294 "",
2295 "/* Do clr. */",
2296 "z = u;",
2297 "res = 0;",
2298 "res_grd = 0;",
2299 "goto assign_z;",
2300 },
2301 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2302 "unsigned Sx = DSP_R (x);",
2303 "int Sx_grd = GET_DSP_GRD (x);",
2304 "int i = 16;",
2305 "",
2306 "if (Sx_grd < 0)",
2307 " {",
2308 " Sx_grd = ~Sx_grd;",
2309 " Sx = ~Sx;",
2310 " }",
2311 "if (Sx_grd)",
2312 " {",
2313 " Sx = Sx_grd;",
2314 " res = -2;",
2315 " }",
2316 "else if (Sx)",
2317 " res = 30;",
2318 "else",
2319 " res = 31;",
2320 "do",
2321 " {",
2322 " if (Sx & ~0 << i)",
2323 " {",
2324 " res -= i;",
2325 " Sx >>= i;",
2326 " }",
2327 " }",
2328 "while (i >>= 1);",
2329 "res <<= 16;",
2330 "res_grd = SIGN32 (res);",
2331 "carry = 0;",
2332 "overflow = 0;",
2333 "ADD_SUB_GE;",
2334 },
2335 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2336 "unsigned Sy = DSP_R (y);",
2337 "int i;",
2338 "",
2339 "if (Sy < 0)",
2340 " Sy = ~Sy;",
2341 "Sy <<= 1;",
2342 "res = 31;",
2343 "do",
2344 " {",
2345 " if (Sy & ~0 << i)",
2346 " {",
2347 " res -= i;",
2348 " Sy >>= i;",
2349 " }",
2350 " }",
2351 "while (i >>= 1);",
2352 "res <<= 16;",
2353 "res_grd = SIGN32 (res);",
2354 "carry = 0;",
2355 "overflow = 0;",
2356 "ADD_SUB_GE;",
2357 },
2358 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2359 "int Sx = DSP_R (x);",
2360 "int Sx_grd = GET_DSP_GRD (x);",
2361 "",
2362 "res = 0 - Sx;",
2363 "carry = res != 0;",
2364 "res_grd = 0 - Sx_grd - carry;",
2365 "COMPUTE_OVERFLOW;",
2366 "ADD_SUB_GE;",
2367 },
2368 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2369 "res = DSP_R (x);",
2370 "res_grd = GET_DSP_GRD (x);",
2371 "carry = 0;",
2372 "COMPUTE_OVERFLOW;",
2373 "ADD_SUB_GE;",
2374 },
2375 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2376 "int Sy = DSP_R (y);",
2377 "int Sy_grd = SIGN32 (Sy);",
2378 "",
2379 "res = 0 - Sy;",
2380 "carry = res != 0;",
2381 "res_grd = 0 - Sy_grd - carry;",
2382 "COMPUTE_OVERFLOW;",
2383 "ADD_SUB_GE;",
2384 },
2385 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2386 "res = DSP_R (y);",
2387 "res_grd = SIGN32 (res);",
2388 "carry = 0;",
2389 "COMPUTE_OVERFLOW;",
2390 "ADD_SUB_GE;",
2391 },
2392 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2393 "res = MACH;",
2394 "res_grd = SIGN32 (res);",
2395 "goto assign_z;",
2396 },
2397 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2398 "res = MACL;",
2399 "res_grd = SIGN32 (res);",
2400 "goto assign_z;",
2401 },
2402 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2403 "if (0xa05f >> z & 1)",
2404 " RAISE_EXCEPTION (SIGILL);",
2405 "else",
2406 " MACH = DSP_R (z);",
2407 "return;",
2408 },
2409 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2410 "if (0xa05f >> z & 1)",
2411 " RAISE_EXCEPTION (SIGILL);",
2412 "else",
2413 " MACL = DSP_R (z) = res;",
2414 "return;",
2415 },
2416 /* sh4a */
2417 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2418 "int Sx = DSP_R (x);",
2419 "",
2420 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2421 "res_grd = GET_DSP_GRD (x);",
2422 "carry = 0;",
2423 "overflow = 0;",
2424 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2425 },
2426 /* sh4a */
2427 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2428 "int Sy = DSP_R (y);",
2429 "",
2430 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2431 "res_grd = SIGN32 (Sy);",
2432 "carry = 0;",
2433 "overflow = 0;",
2434 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2435 },
2436
2437 {0, 0}
2438};
2439
2440/* Tables of things to put into enums for sh-opc.h */
2441static char *nibble_type_list[] =
2442{
2443 "HEX_0",
2444 "HEX_1",
2445 "HEX_2",
2446 "HEX_3",
2447 "HEX_4",
2448 "HEX_5",
2449 "HEX_6",
2450 "HEX_7",
2451 "HEX_8",
2452 "HEX_9",
2453 "HEX_A",
2454 "HEX_B",
2455 "HEX_C",
2456 "HEX_D",
2457 "HEX_E",
2458 "HEX_F",
2459 "REG_N",
2460 "REG_M",
2461 "BRANCH_12",
2462 "BRANCH_8",
2463 "DISP_8",
2464 "DISP_4",
2465 "IMM_4",
2466 "IMM_4BY2",
2467 "IMM_4BY4",
2468 "PCRELIMM_8BY2",
2469 "PCRELIMM_8BY4",
2470 "IMM_8",
2471 "IMM_8BY2",
2472 "IMM_8BY4",
2473 0
2474};
2475static
2476char *arg_type_list[] =
2477{
2478 "A_END",
2479 "A_BDISP12",
2480 "A_BDISP8",
2481 "A_DEC_M",
2482 "A_DEC_N",
2483 "A_DISP_GBR",
2484 "A_DISP_PC",
2485 "A_DISP_REG_M",
2486 "A_DISP_REG_N",
2487 "A_GBR",
2488 "A_IMM",
2489 "A_INC_M",
2490 "A_INC_N",
2491 "A_IND_M",
2492 "A_IND_N",
2493 "A_IND_R0_REG_M",
2494 "A_IND_R0_REG_N",
2495 "A_MACH",
2496 "A_MACL",
2497 "A_PR",
2498 "A_R0",
2499 "A_R0_GBR",
2500 "A_REG_M",
2501 "A_REG_N",
2502 "A_SR",
2503 "A_VBR",
2504 "A_SSR",
2505 "A_SPC",
2506 0,
2507};
2508
2509static void
2510make_enum_list (name, s)
2511 char *name;
2512 char **s;
2513{
2514 int i = 1;
2515 printf ("typedef enum {\n");
2516 while (*s)
2517 {
2518 printf ("\t%s,\n", *s);
2519 s++;
2520 i++;
2521 }
2522 printf ("} %s;\n", name);
2523}
2524
2525static int
2526qfunc (a, b)
2527 op *a;
2528 op *b;
2529{
2530 char bufa[9];
2531 char bufb[9];
2532 int diff;
2533
2534 memcpy (bufa, a->code, 4);
2535 memcpy (bufa + 4, a->code + 12, 4);
2536 bufa[8] = 0;
2537
2538 memcpy (bufb, b->code, 4);
2539 memcpy (bufb + 4, b->code + 12, 4);
2540 bufb[8] = 0;
2541 diff = strcmp (bufa, bufb);
2542 /* Stabilize the sort, so that later entries can override more general
2543 preceding entries. */
2544 return diff ? diff : a - b;
2545}
2546
2547static void
2548sorttab ()
2549{
2550 op *p = tab;
2551 int len = 0;
2552
2553 while (p->name)
2554 {
2555 p++;
2556 len++;
2557 }
2558 qsort (tab, len, sizeof (*p), qfunc);
2559}
2560
2561static void
2562gengastab ()
2563{
2564 op *p;
2565 sorttab ();
2566 for (p = tab; p->name; p++)
2567 {
2568 printf ("%s %-30s\n", p->code, p->name);
2569 }
2570}
2571
2572static unsigned short table[1 << 16];
2573
2574static int warn_conflicts = 0;
2575
2576static void
2577conflict_warn (val, i)
2578 int val;
2579 int i;
2580{
2581 int ix, key;
2582 int j = table[val];
2583
2584 fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2585 val, i, table[val]);
2586
2587 for (ix = sizeof (tab) / sizeof (tab[0]); ix >= 0; ix--)
2588 if (tab[ix].index == i || tab[ix].index == j)
2589 {
2590 key = ((tab[ix].code[0] - '0') << 3) +
2591 ((tab[ix].code[1] - '0') << 2) +
2592 ((tab[ix].code[2] - '0') << 1) +
2593 ((tab[ix].code[3] - '0'));
2594
2595 if (val >> 12 == key)
2596 fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name);
2597 }
2598
2599 for (ix = sizeof (movsxy_tab) / sizeof (movsxy_tab[0]); ix >= 0; ix--)
2600 if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
2601 {
2602 key = ((movsxy_tab[ix].code[0] - '0') << 3) +
2603 ((movsxy_tab[ix].code[1] - '0') << 2) +
2604 ((movsxy_tab[ix].code[2] - '0') << 1) +
2605 ((movsxy_tab[ix].code[3] - '0'));
2606
2607 if (val >> 12 == key)
2608 fprintf (stderr, " %s -- %s\n",
2609 movsxy_tab[ix].code, movsxy_tab[ix].name);
2610 }
2611
2612 for (ix = sizeof (ppi_tab) / sizeof (ppi_tab[0]); ix >= 0; ix--)
2613 if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
2614 {
2615 key = ((ppi_tab[ix].code[0] - '0') << 3) +
2616 ((ppi_tab[ix].code[1] - '0') << 2) +
2617 ((ppi_tab[ix].code[2] - '0') << 1) +
2618 ((ppi_tab[ix].code[3] - '0'));
2619
2620 if (val >> 12 == key)
2621 fprintf (stderr, " %s -- %s\n",
2622 ppi_tab[ix].code, ppi_tab[ix].name);
2623 }
2624}
2625
2626/* Take an opcode, expand all varying fields in it out and fill all the
2627 right entries in 'table' with the opcode index. */
2628
2629static void
2630expand_opcode (val, i, s)
2631 int val;
2632 int i;
2633 char *s;
2634{
2635 if (*s == 0)
2636 {
2637 if (warn_conflicts && table[val] != 0)
2638 conflict_warn (val, i);
2639 table[val] = i;
2640 }
2641 else
2642 {
2643 int j = 0, m = 0;
2644
2645 switch (s[0])
2646 {
2647 default:
2648 fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
2649 exit (1);
2650 case '0':
2651 case '1':
2652 /* Consume an arbitrary number of ones and zeros. */
2653 do {
2654 j = (j << 1) + (s[m++] - '0');
2655 } while (s[m] == '0' || s[m] == '1');
2656 expand_opcode ((val << m) | j, i, s + m);
2657 break;
2658 case 'N': /* NN -- four-way fork */
2659 for (j = 0; j < 4; j++)
2660 expand_opcode ((val << 2) | j, i, s + 2);
2661 break;
2662 case 'x': /* xx or xy -- two-way or four-way fork */
2663 for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1))
2664 expand_opcode ((val << 2) | j, i, s + 2);
2665 break;
2666 case 'y': /* yy or yx -- two-way or four-way fork */
2667 for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++)
2668 expand_opcode ((val << 2) | j, i, s + 2);
2669 break;
2670 case '?': /* Seven-way "wildcard" fork for movxy */
2671 expand_opcode ((val << 2), i, s + 2);
2672 for (j = 1; j < 4; j++)
2673 {
2674 expand_opcode ((val << 2) | j, i, s + 2);
2675 expand_opcode ((val << 2) | (j + 16), i, s + 2);
2676 }
2677 break;
2678 case 'i': /* eg. "i8*1" */
2679 case '.': /* "...." is a wildcard */
2680 case 'n':
2681 case 'm':
2682 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2683 for (j = 0; j < 16; j++)
2684 expand_opcode ((val << 4) | j, i, s + 4);
2685 break;
2686 case 'e':
2687 /* eeee -- even numbered register:
2688 8 way fork. */
2689 for (j = 0; j < 15; j += 2)
2690 expand_opcode ((val << 4) | j, i, s + 4);
2691 break;
2692 case 'M':
2693 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2694 MMMM -- 10-way fork */
2695 expand_opcode ((val << 4) | 5, i, s + 4);
2696 for (j = 7; j < 16; j++)
2697 expand_opcode ((val << 4) | j, i, s + 4);
2698 break;
2699 case 'G':
2700 /* A1G, A0G:
2701 GGGG -- two-way fork */
2702 for (j = 13; j <= 15; j +=2)
2703 expand_opcode ((val << 4) | j, i, s + 4);
2704 break;
2705 case 's':
2706 /* ssss -- 10-way fork */
2707 /* System registers mach, macl, pr: */
2708 for (j = 0; j < 3; j++)
2709 expand_opcode ((val << 4) | j, i, s + 4);
2710 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2711 for (j = 5; j < 12; j++)
2712 expand_opcode ((val << 4) | j, i, s + 4);
2713 break;
2714 case 'X':
2715 /* XX/XY -- 2/4 way fork. */
2716 for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1))
2717 expand_opcode ((val << 2) | j, i, s + 2);
2718 break;
2719 case 'a':
2720 /* aa/ax -- 2/4 way fork. */
2721 for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1))
2722 expand_opcode ((val << 2) | j, i, s + 2);
2723 break;
2724 case 'Y':
2725 /* YY/YX -- 2/4 way fork. */
2726 for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1)
2727 expand_opcode ((val << 2) | j, i, s + 2);
2728 break;
2729 case 'A':
2730 /* AA/AY: 2/4 way fork. */
2731 for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1)
2732 expand_opcode ((val << 2) | j, i, s + 2);
2733 break;
2734 case 'v':
2735 /* vv(VV) -- 4(16) way fork. */
2736 /* Vector register fv0/4/8/12. */
2737 if (s[2] == 'V')
2738 {
2739 /* 2 vector registers. */
2740 for (j = 0; j < 15; j++)
2741 expand_opcode ((val << 4) | j, i, s + 4);
2742 }
2743 else
2744 {
2745 /* 1 vector register. */
2746 for (j = 0; j < 4; j += 1)
2747 expand_opcode ((val << 2) | j, i, s + 2);
2748 }
2749 break;
2750 }
2751 }
2752}
2753
2754/* Print the jump table used to index an opcode into a switch
2755 statement entry. */
2756
2757static void
2758dumptable (name, size, start)
2759 char *name;
2760 int size;
2761 int start;
2762{
2763 int lump = 256;
2764 int online = 16;
2765
2766 int i = start;
2767
2768 printf ("unsigned short %s[%d]={\n", name, size);
2769 while (i < start + size)
2770 {
2771 int j = 0;
2772
2773 printf ("/* 0x%x */\n", i);
2774
2775 while (j < lump)
2776 {
2777 int k = 0;
2778 while (k < online)
2779 {
2780 printf ("%2d", table[i + j + k]);
2781 if (j + k < lump)
2782 printf (",");
2783
2784 k++;
2785 }
2786 j += k;
2787 printf ("\n");
2788 }
2789 i += j;
2790 }
2791 printf ("};\n");
2792}
2793
2794
2795static void
2796filltable (p)
2797 op *p;
2798{
2799 static int index = 1;
2800
2801 sorttab ();
2802 for (; p->name; p++)
2803 {
2804 p->index = index++;
2805 expand_opcode (0, p->index, p->code);
2806 }
2807}
2808
2809/* Table already contains all the switch case tags for 16-bit opcode double
2810 data transfer (ddt) insns, and the switch case tag for processing parallel
2811 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2812 latter tag to represent all combinations of ppi with ddt. */
2813static void
2814expand_ppi_movxy ()
2815{
2816 int i;
2817
2818 for (i = 0xf000; i < 0xf400; i++)
2819 if (table[i])
2820 table[i + 0x800] = table[0xf800];
2821}
2822
2823static void
2824gensim_caselist (p)
2825 op *p;
2826{
2827 for (; p->name; p++)
2828 {
2829 int j;
2830 int sextbit = -1;
2831 int needm = 0;
2832 int needn = 0;
2833
2834 char *s = p->code;
2835
2836 printf (" /* %s %s */\n", p->name, p->code);
2837 printf (" case %d: \n", p->index);
2838
2839 printf (" {\n");
2840 while (*s)
2841 {
2842 switch (*s)
2843 {
2844 default:
2845 fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2846 *s);
2847 exit (1);
2848 break;
2849 case '?':
2850 /* Wildcard expansion, nothing to do here. */
2851 s += 2;
2852 break;
2853 case 'v':
2854 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2855 s += 2;
2856 break;
2857 case 'V':
2858 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2859 s += 2;
2860 break;
2861 case '0':
2862 case '1':
2863 s += 2;
2864 break;
2865 case '.':
2866 s += 4;
2867 break;
2868 case 'n':
2869 case 'e':
2870 printf (" int n = (iword >> 8) & 0xf;\n");
2871 needn = 1;
2872 s += 4;
2873 break;
2874 case 'N':
2875 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2876 s += 2;
2877 break;
2878 case 'x':
2879 if (s[1] == 'y') /* xy */
2880 {
2881 printf (" int n = (iword & 3) ? \n");
2882 printf (" ((iword >> 9) & 1) + 4 : \n");
2883 printf (" REG_xy ((iword >> 8) & 3);\n");
2884 }
2885 else
2886 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2887 needn = 1;
2888 s += 2;
2889 break;
2890 case 'y':
2891 if (s[1] == 'x') /* yx */
2892 {
2893 printf (" int n = (iword & 0xc) ? \n");
2894 printf (" ((iword >> 8) & 1) + 6 : \n");
2895 printf (" REG_yx ((iword >> 8) & 3);\n");
2896 }
2897 else
2898 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2899 needn = 1;
2900 s += 2;
2901 break;
2902 case 'm':
2903 needm = 1;
2904 case 's':
2905 case 'M':
2906 case 'G':
2907 printf (" int m = (iword >> 4) & 0xf;\n");
2908 s += 4;
2909 break;
2910 case 'X':
2911 if (s[1] == 'Y') /* XY */
2912 {
2913 printf (" int m = (iword & 3) ? \n");
2914 printf (" ((iword >> 7) & 1) + 8 : \n");
2915 printf (" DSP_xy ((iword >> 6) & 3);\n");
2916 }
2917 else
2918 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2919 s += 2;
2920 break;
2921 case 'a':
2922 if (s[1] == 'x') /* ax */
2923 {
2924 printf (" int m = (iword & 3) ? \n");
2925 printf (" 7 - ((iword >> 6) & 2) : \n");
2926 printf (" DSP_ax ((iword >> 6) & 3);\n");
2927 }
2928 else
2929 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2930 s += 2;
2931 break;
2932 case 'Y':
2933 if (s[1] == 'X') /* YX */
2934 {
2935 printf (" int m = (iword & 0xc) ? \n");
2936 printf (" ((iword >> 6) & 1) + 10 : \n");
2937 printf (" DSP_yx ((iword >> 6) & 3);\n");
2938 }
2939 else
2940 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2941 s += 2;
2942 break;
2943 case 'A':
2944 if (s[1] == 'Y') /* AY */
2945 {
2946 printf (" int m = (iword & 0xc) ? \n");
2947 printf (" 7 - ((iword >> 5) & 2) : \n");
2948 printf (" DSP_ay ((iword >> 6) & 3);\n");
2949 }
2950 else
2951 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2952 s += 2;
2953 break;
2954
2955 case 'i':
2956 printf (" int i = (iword & 0x");
2957
2958 switch (s[1])
2959 {
2960 default:
2961 fprintf (stderr,
2962 "gensim_caselist: Unknown char '%c' in %s\n",
2963 s[1], s);
2964 exit (1);
2965 break;
2966 case '4':
2967 printf ("f");
2968 break;
2969 case '8':
2970 printf ("ff");
2971 break;
2972 case '1':
2973 sextbit = 12;
2974 printf ("fff");
2975 break;
2976 }
2977 printf (")");
2978
2979 switch (s[3])
2980 {
2981 default:
2982 fprintf (stderr,
2983 "gensim_caselist: Unknown char '%c' in %s\n",
2984 s[3], s);
2985 exit (1);
2986 break;
2987 case '.': /* eg. "i12." */
2988 break;
2989 case '1':
2990 break;
2991 case '2':
2992 printf (" << 1");
2993 break;
2994 case '4':
2995 printf (" << 2");
2996 break;
2997 }
2998 printf (";\n");
2999 s += 4;
3000 }
3001 }
3002 if (sextbit > 0)
3003 {
3004 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3005 sextbit - 1, sextbit - 1);
3006 }
3007
3008 if (needm && needn)
3009 printf (" TB (m,n);\n");
3010 else if (needm)
3011 printf (" TL (m);\n");
3012 else if (needn)
3013 printf (" TL (n);\n");
3014
3015 {
3016 /* Do the refs. */
3017 char *r;
3018 for (r = p->refs; *r; r++)
3019 {
3020 if (*r == 'f') printf (" CREF (15);\n");
3021 if (*r == '-')
3022 {
3023 printf (" {\n");
3024 printf (" int i = n;\n");
3025 printf (" do {\n");
3026 printf (" CREF (i);\n");
3027 printf (" } while (i-- > 0);\n");
3028 printf (" }\n");
3029 }
3030 if (*r == '+')
3031 {
3032 printf (" {\n");
3033 printf (" int i = n;\n");
3034 printf (" do {\n");
3035 printf (" CREF (i);\n");
3036 printf (" } while (i++ < 14);\n");
3037 printf (" }\n");
3038 }
3039 if (*r == '0') printf (" CREF (0);\n");
3040 if (*r == '8') printf (" CREF (8);\n");
3041 if (*r == '9') printf (" CREF (9);\n");
3042 if (*r == 'n') printf (" CREF (n);\n");
3043 if (*r == 'm') printf (" CREF (m);\n");
3044 }
3045 }
3046
3047 printf (" {\n");
3048 for (j = 0; j < MAX_NR_STUFF; j++)
3049 {
3050 if (p->stuff[j])
3051 {
3052 printf (" %s\n", p->stuff[j]);
3053 }
3054 }
3055 printf (" }\n");
3056
3057 {
3058 /* Do the defs. */
3059 char *r;
3060 for (r = p->defs; *r; r++)
3061 {
3062 if (*r == 'f') printf (" CDEF (15);\n");
3063 if (*r == '-')
3064 {
3065 printf (" {\n");
3066 printf (" int i = n;\n");
3067 printf (" do {\n");
3068 printf (" CDEF (i);\n");
3069 printf (" } while (i-- > 0);\n");
3070 printf (" }\n");
3071 }
3072 if (*r == '+')
3073 {
3074 printf (" {\n");
3075 printf (" int i = n;\n");
3076 printf (" do {\n");
3077 printf (" CDEF (i);\n");
3078 printf (" } while (i++ < 14);\n");
3079 printf (" }\n");
3080 }
3081 if (*r == '0') printf (" CDEF (0);\n");
3082 if (*r == 'n') printf (" CDEF (n);\n");
3083 if (*r == 'm') printf (" CDEF (m);\n");
3084 }
3085 }
3086
3087 printf (" break;\n");
3088 printf (" }\n");
3089 }
3090}
3091
3092static void
3093gensim ()
3094{
3095 printf ("{\n");
3096 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3097 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3098 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3099 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3100 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3101 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3102 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3103 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3104 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3105 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3106 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3107 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3108 printf (" switch (jump_table[iword]) {\n");
3109
3110 gensim_caselist (tab);
3111 gensim_caselist (movsxy_tab);
3112
3113 printf (" default:\n");
3114 printf (" {\n");
3115 printf (" RAISE_EXCEPTION (SIGILL);\n");
3116 printf (" }\n");
3117 printf (" }\n");
3118 printf ("}\n");
3119}
3120
3121static void
3122gendefines ()
3123{
3124 op *p;
3125 filltable (tab);
3126 for (p = tab; p->name; p++)
3127 {
3128 char *s = p->name;
3129 printf ("#define OPC_");
3130 while (*s) {
3131 if (isupper (*s))
3132 *s = tolower (*s);
3133 if (isalpha (*s))
3134 printf ("%c", *s);
3135 if (*s == ' ')
3136 printf ("_");
3137 if (*s == '@')
3138 printf ("ind_");
3139 if (*s == ',')
3140 printf ("_");
3141 s++;
3142 }
3143 printf (" %d\n",p->index);
3144 }
3145}
3146
3147static int ppi_index;
3148
3149/* Take a ppi code, expand all varying fields in it and fill all the
3150 right entries in 'table' with the opcode index.
3151 NOTE: tail recursion optimization removed for simplicity. */
3152
3153static void
3154expand_ppi_code (val, i, s)
3155 int val;
3156 int i;
3157 char *s;
3158{
3159 int j;
3160
3161 switch (s[0])
3162 {
3163 default:
3164 fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]);
3165 exit (2);
3166 break;
3167 case 'g':
3168 case 'z':
3169 if (warn_conflicts && table[val] != 0)
3170 conflict_warn (val, i);
3171
3172 /* The last four bits are disregarded for the switch table. */
3173 table[val] = i;
3174 return;
3175 case 'm':
3176 /* Four-bit expansion. */
3177 for (j = 0; j < 16; j++)
3178 expand_ppi_code ((val << 4) + j, i, s + 4);
3179 break;
3180 case '.':
3181 case '0':
3182 expand_ppi_code ((val << 1), i, s + 1);
3183 break;
3184 case '1':
3185 expand_ppi_code ((val << 1) + 1, i, s + 1);
3186 break;
3187 case 'i':
3188 case 'e': case 'f':
3189 case 'x': case 'y':
3190 expand_ppi_code ((val << 1), i, s + 1);
3191 expand_ppi_code ((val << 1) + 1, i, s + 1);
3192 break;
3193 case 'c':
3194 expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2);
3195 expand_ppi_code ((val << 2) + 2, i, s + 2);
3196 expand_ppi_code ((val << 2) + 3, i, s + 2);
3197 break;
3198 }
3199}
3200
3201static void
3202ppi_filltable ()
3203{
3204 op *p;
3205 ppi_index = 1;
3206
3207 for (p = ppi_tab; p->name; p++)
3208 {
3209 p->index = ppi_index++;
3210 expand_ppi_code (0, p->index, p->code);
3211 }
3212}
3213
3214static void
3215ppi_gensim ()
3216{
3217 op *p = ppi_tab;
3218
3219 printf ("#define DSR_MASK_G 0x80\n");
3220 printf ("#define DSR_MASK_Z 0x40\n");
3221 printf ("#define DSR_MASK_N 0x20\n");
3222 printf ("#define DSR_MASK_V 0x10\n");
3223 printf ("\n");
3224 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3225 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3226 printf (" if (overflow && S) \\\n");
3227 printf (" { \\\n");
3228 printf (" if (res_grd & 0x80) \\\n");
3229 printf (" { \\\n");
3230 printf (" res = 0x80000000; \\\n");
3231 printf (" res_grd |= 0xff; \\\n");
3232 printf (" } \\\n");
3233 printf (" else \\\n");
3234 printf (" { \\\n");
3235 printf (" res = 0x7fffffff; \\\n");
3236 printf (" res_grd &= ~0xff; \\\n");
3237 printf (" } \\\n");
3238 printf (" overflow = 0; \\\n");
3239 printf (" } \\\n");
3240 printf ("} while (0)\n");
3241 printf ("\n");
3242 printf ("#define ADD_SUB_GE \\\n");
3243 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3244 printf ("\n");
3245 printf ("static void\n");
3246 printf ("ppi_insn (iword)\n");
3247 printf (" int iword;\n");
3248 printf ("{\n");
3249 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3250 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
3251 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3252 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
3253 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3254 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
3255 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3256 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
3257 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3258 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
3259 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3260 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
3261 printf ("\n");
3262 printf (" int z;\n");
3263 printf (" int res, res_grd;\n");
3264 printf (" int carry, overflow, greater_equal;\n");
3265 printf ("\n");
3266 printf (" switch (ppi_table[iword >> 4]) {\n");
3267
3268 for (; p->name; p++)
3269 {
3270 int shift, j;
3271 int cond = 0;
3272 int havedecl = 0;
3273
3274 char *s = p->code;
3275
3276 printf (" /* %s %s */\n", p->name, p->code);
3277 printf (" case %d: \n", p->index);
3278
3279 printf (" {\n");
3280 for (shift = 16; *s; )
3281 {
3282 switch (*s)
3283 {
3284 case 'i':
3285 printf (" int i = (iword >> 4) & 0x7f;\n");
3286 s += 6;
3287 break;
3288 case 'e':
3289 case 'f':
3290 case 'x':
3291 case 'y':
3292 case 'g':
3293 case 'u':
3294 shift -= 2;
3295 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3296 *s, *s, shift);
3297 havedecl = 1;
3298 s += 2;
3299 break;
3300 case 'c':
3301 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3302 printf ("\treturn;\n");
3303 printf (" }\n");
3304 printf (" case %d: \n", p->index + 1);
3305 printf (" {\n");
3306 cond = 1;
3307 case '0':
3308 case '1':
3309 case '.':
3310 shift -= 2;
3311 s += 2;
3312 break;
3313 case 'z':
3314 if (havedecl)
3315 printf ("\n");
3316 printf (" z = iword & 0xf;\n");
3317 havedecl = 2;
3318 s += 4;
3319 break;
3320 }
3321 }
3322 if (havedecl == 1)
3323 printf ("\n");
3324 else if (havedecl == 2)
3325 printf (" {\n");
3326 for (j = 0; j < MAX_NR_STUFF; j++)
3327 {
3328 if (p->stuff[j])
3329 {
3330 printf (" %s%s\n",
3331 (havedecl == 2 ? " " : ""),
3332 p->stuff[j]);
3333 }
3334 }
3335 if (havedecl == 2)
3336 printf (" }\n");
3337 if (cond)
3338 {
3339 printf (" if (iword & 0x200)\n");
3340 printf (" goto assign_z;\n");
3341 }
3342 printf (" break;\n");
3343 printf (" }\n");
3344 }
3345
3346 printf (" default:\n");
3347 printf (" {\n");
3348 printf (" RAISE_EXCEPTION (SIGILL);\n");
3349 printf (" return;\n");
3350 printf (" }\n");
3351 printf (" }\n");
3352 printf (" DSR &= ~0xf1;\n");
3353 printf (" if (res || res_grd)\n");
3354 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3355 printf (" else\n");
3356 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3357 printf (" assign_dc:\n");
3358 printf (" switch (DSR >> 1 & 7)\n");
3359 printf (" {\n");
3360 printf (" case 0: /* Carry Mode */\n");
3361 printf (" DSR |= carry;\n");
3362 printf (" case 1: /* Negative Value Mode */\n");
3363 printf (" DSR |= res_grd >> 7 & 1;\n");
3364 printf (" case 2: /* Zero Value Mode */\n");
3365 printf (" DSR |= DSR >> 6 & 1;\n");
3366 printf (" case 3: /* Overflow mode\n");
3367 printf (" DSR |= overflow >> 4;\n");
3368 printf (" case 4: /* Signed Greater Than Mode */\n");
3369 printf (" DSR |= DSR >> 7 & 1;\n");
3370 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
3371 printf (" DSR |= greater_equal >> 7;\n");
3372 printf (" }\n");
3373 printf (" assign_z:\n");
3374 printf (" if (0xa05f >> z & 1)\n");
3375 printf (" {\n");
3376 printf (" RAISE_EXCEPTION (SIGILL);\n");
3377 printf (" return;\n");
3378 printf (" }\n");
3379 printf (" DSP_R (z) = res;\n");
3380 printf (" DSP_GRD (z) = res_grd;\n");
3381 printf ("}\n");
3382}
3383
3384int
3385main (ac, av)
3386 int ac;
3387 char **av;
3388{
3389 /* Verify the table before anything else. */
3390 {
3391 op *p;
3392 for (p = tab; p->name; p++)
3393 {
3394 /* Check that the code field contains 16 bits. */
3395 if (strlen (p->code) != 16)
3396 {
3397 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
3398 p->code, strlen (p->code), p->name);
3399 abort ();
3400 }
3401 }
3402 }
3403
3404 /* Now generate the requested data. */
3405 if (ac > 1)
3406 {
3407 if (ac > 2 && strcmp (av[2], "-w") == 0)
3408 {
3409 warn_conflicts = 1;
3410 }
3411 if (strcmp (av[1], "-t") == 0)
3412 {
3413 gengastab ();
3414 }
3415 else if (strcmp (av[1], "-d") == 0)
3416 {
3417 gendefines ();
3418 }
3419 else if (strcmp (av[1], "-s") == 0)
3420 {
3421 filltable (tab);
3422 dumptable ("sh_jump_table", 1 << 16, 0);
3423
3424 memset (table, 0, sizeof table);
3425 filltable (movsxy_tab);
3426 expand_ppi_movxy ();
3427 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3428
3429 memset (table, 0, sizeof table);
3430 ppi_filltable ();
3431 dumptable ("ppi_table", 1 << 12, 0);
3432 }
3433 else if (strcmp (av[1], "-x") == 0)
3434 {
3435 filltable (tab);
3436 filltable (movsxy_tab);
3437 gensim ();
3438 }
3439 else if (strcmp (av[1], "-p") == 0)
3440 {
3441 ppi_filltable ();
3442 ppi_gensim ();
3443 }
3444 }
3445 else
3446 fprintf (stderr, "Opcode table generation no longer supported.\n");
3447 return 0;
3448}
This page took 0.035855 seconds and 4 git commands to generate.