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