]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh/gencode.c
opcodes: bfin: simplify field width processing and fix build warnings
[thirdparty/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 /* Allow for the case where m == n. */
974 "int t = R[m];",
975 "MA (1);",
976 "R[n] -= 1;",
977 "WBAT (R[n], t);",
978 },
979 { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
980 "MA (1);",
981 "WBAT (R[n], R0);",
982 "R[n] += 1;",
983 },
984 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
985 "MA (1);",
986 "R[n] = RSBAT (R[m]);",
987 "L (n);",
988 },
989
990 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
991 "MA (1);",
992 "R0 = RLAT (i + GBR);",
993 "L (0);",
994 },
995 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
996 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
997 "MA (1);",
998 "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
999 "L (n);",
1000 },
1001 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1002 "MA (1);",
1003 "R[n] = RLAT (i + R[m]);",
1004 "L (n);",
1005 },
1006 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1007 "MA (1);",
1008 "R[n] = RLAT (R0 + R[m]);",
1009 "L (n);",
1010 },
1011 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1012 "MA (1);",
1013 "R[n] = RLAT (R[m]);",
1014 "R[m] += 4;",
1015 "L (n);",
1016 },
1017 { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1018 "MA (1);",
1019 "R[n] -= 4;",
1020 "R0 = RLAT (R[n]);",
1021 "L (0);",
1022 },
1023 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1024 "MA (1);",
1025 "R[n] = RLAT (R[m]);",
1026 "L (n);",
1027 },
1028 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1029 "MA (1);",
1030 "WLAT (i + GBR, R0);",
1031 },
1032 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1033 "MA (1);",
1034 "WLAT (i + R[n], R[m]);",
1035 },
1036 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1037 "MA (1);",
1038 "WLAT (R0 + R[n], R[m]);",
1039 },
1040 { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1041 /* Allow for the case where m == n. */
1042 "int t = R[m];",
1043 "MA (1) ;",
1044 "R[n] -= 4;",
1045 "WLAT (R[n], t);",
1046 },
1047 { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1048 "MA (1) ;",
1049 "WLAT (R[n], R0);",
1050 "R[n] += 4;",
1051 },
1052 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1053 "MA (1);",
1054 "WLAT (R[n], R[m]);",
1055 },
1056
1057 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1058 "MA (1);",
1059 "R0 = RSWAT (i + GBR);",
1060 "L (0);",
1061 },
1062 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1063 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1064 "MA (1);",
1065 "R[n] = RSWAT (PH2T (PC + 4 + i));",
1066 "L (n);",
1067 },
1068 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1069 "MA (1);",
1070 "R0 = RSWAT (i + R[m]);",
1071 "L (0);",
1072 },
1073 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1074 "MA (1);",
1075 "R[n] = RSWAT (R0 + R[m]);",
1076 "L (n);",
1077 },
1078 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1079 "MA (1);",
1080 "R[n] = RSWAT (R[m]);",
1081 "R[m] += 2;",
1082 "L (n);",
1083 },
1084 { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1085 "MA (1);",
1086 "R[n] -= 2;",
1087 "R0 = RSWAT (R[n]);",
1088 "L (0);",
1089 },
1090 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1091 "MA (1);",
1092 "R[n] = RSWAT (R[m]);",
1093 "L (n);",
1094 },
1095 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1096 "MA (1);",
1097 "WWAT (i + GBR, R0);",
1098 },
1099 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1100 "MA (1);",
1101 "WWAT (i + R[m], R0);",
1102 },
1103 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1104 "MA (1);",
1105 "WWAT (R0 + R[n], R[m]);",
1106 },
1107 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1108 /* Allow for the case where m == n. */
1109 "int t = R[m];",
1110 "MA (1);",
1111 "R[n] -= 2;",
1112 "WWAT (R[n], t);",
1113 },
1114 { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1115 "MA (1);",
1116 "WWAT (R[n], R0);",
1117 "R[n] += 2;",
1118 },
1119 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1120 "MA (1);",
1121 "WWAT (R[n], R[m]);",
1122 },
1123
1124 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1125 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1126 "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1127 },
1128
1129 { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1130 "/* We don't simulate cache, so this insn is identical to mov. */",
1131 "MA (1);",
1132 "WLAT (R[n], R[0]);",
1133 },
1134
1135 { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1136 "/* LDST -> T */",
1137 "SET_SR_T (LDST);",
1138 "/* if (T) R0 -> (Rn) */",
1139 "if (T)",
1140 " WLAT (R[n], R[0]);",
1141 "/* 0 -> LDST */",
1142 "SET_LDST (0);",
1143 },
1144
1145 { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1146 "/* 1 -> LDST */",
1147 "SET_LDST (1);",
1148 "/* (Rn) -> R0 */",
1149 "R[0] = RLAT (R[n]);",
1150 "/* if (interrupt/exception) 0 -> LDST */",
1151 "/* (we don't simulate asynchronous interrupts/exceptions) */",
1152 },
1153
1154 { "n", "", "movt <REG_N>", "0000nnnn00101001",
1155 "R[n] = T;",
1156 },
1157 { "", "", "movrt <REG_N>", "0000nnnn00111001",
1158 "R[n] = (T == 0);",
1159 },
1160 { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1161 "int regn = R[n];",
1162 "int e = target_little_endian ? 3 : 0;",
1163 "MA (1);",
1164 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1165 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1166 "L (0);",
1167 },
1168 { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1169 "int regn = R[n];",
1170 "int e = target_little_endian ? 3 : 0;",
1171 "MA (1);",
1172 "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1173 " (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1174 "R[n] += 4;",
1175 "L (0);",
1176 },
1177 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1178 "MACL = ((int) R[n]) * ((int) R[m]);",
1179 },
1180 #if 0 /* FIXME: The above cast to int is not really portable.
1181 It should be replaced by a SEXT32 macro. */
1182 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1183 "MACL = R[n] * R[m];",
1184 },
1185 #endif
1186
1187 /* muls.w - see muls */
1188 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1189 "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1190 },
1191
1192 /* mulu.w - see mulu */
1193 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1194 "MACL = (((unsigned int) (unsigned short) R[n])",
1195 " * ((unsigned int) (unsigned short) R[m]));",
1196 },
1197
1198 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1199 "R[n] = - R[m];",
1200 },
1201
1202 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1203 "ult = -T;",
1204 "SET_SR_T (ult > 0);",
1205 "R[n] = ult - R[m];",
1206 "SET_SR_T (T || (R[n] > ult));",
1207 },
1208
1209 { "", "", "nop", "0000000000001001",
1210 "/* nop */",
1211 },
1212
1213 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1214 "R[n] = ~R[m];",
1215 },
1216
1217 /* sh4a */
1218 { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1219 "/* Except for the effect on the cache - which is not simulated -",
1220 " this is like a nop. */",
1221 },
1222
1223 { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1224 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1225 "/* FIXME: Cache not implemented */",
1226 },
1227
1228 { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1229 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1230 "/* FIXME: Cache not implemented */",
1231 },
1232
1233 { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1234 "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop. */",
1235 "/* FIXME: Cache not implemented */",
1236 },
1237
1238 { "0", "", "or #<imm>,R0", "11001011i8*1....",
1239 "R0 |= i;",
1240 },
1241 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1242 "R[n] |= R[m];",
1243 },
1244 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1245 "MA (1);",
1246 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1247 },
1248
1249 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1250 "/* Except for the effect on the cache - which is not simulated -",
1251 " this is like a nop. */",
1252 },
1253
1254 /* sh4a */
1255 { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1256 "/* Except for the effect on the cache - which is not simulated -",
1257 " this is like a nop. */",
1258 },
1259
1260 /* sh4a */
1261 { "", "", "synco", "0000000010101011",
1262 "/* Except for the effect on the pipeline - which is not simulated -",
1263 " this is like a nop. */",
1264 },
1265
1266 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1267 "ult = R[n] < 0;",
1268 "R[n] = (R[n] << 1) | T;",
1269 "SET_SR_T (ult);",
1270 },
1271
1272 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1273 "ult = R[n] & 1;",
1274 "R[n] = (UR[n] >> 1) | (T << 31);",
1275 "SET_SR_T (ult);",
1276 },
1277
1278 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1279 "SET_SR_T (R[n] < 0);",
1280 "R[n] <<= 1;",
1281 "R[n] |= T;",
1282 },
1283
1284 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1285 "SET_SR_T (R[n] & 1);",
1286 "R[n] = UR[n] >> 1;",
1287 "R[n] |= (T << 31);",
1288 },
1289
1290 { "", "", "rte", "0000000000101011",
1291 #if 0
1292 /* SH-[12] */
1293 "int tmp = PC;",
1294 "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1295 "R[15] += 4;",
1296 "SET_SR (RLAT (R[15]) & 0x3f3);",
1297 "R[15] += 4;",
1298 "Delay_Slot (PC + 2);",
1299 #else
1300 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1301 "SET_SR (SSR);",
1302 "SET_NIP (PT2H (SPC));",
1303 "cycles += 2;",
1304 "Delay_Slot (PC + 2);",
1305 #endif
1306 },
1307
1308 { "", "", "rts", "0000000000001011",
1309 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1310 "SET_NIP (PT2H (PR));",
1311 "cycles += 2;",
1312 "Delay_Slot (PC + 2);",
1313 },
1314 { "", "", "rts/n", "0000000001101011",
1315 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1316 "SET_NIP (PT2H (PR));",
1317 },
1318 { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1319 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1320 "R0 = R[n];",
1321 "L (0);",
1322 "SET_NIP (PT2H (PR));",
1323 },
1324
1325 /* sh4a */
1326 { "", "", "setdmx", "0000000010011000",
1327 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMX;"
1328 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1329 },
1330
1331 /* sh4a */
1332 { "", "", "setdmy", "0000000011001000",
1333 "saved_state.asregs.cregs.named.sr |= SR_MASK_DMY;"
1334 "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1335 },
1336
1337 /* sh-dsp */
1338 { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1339 "SET_RC (R[n]);",
1340 },
1341 { "", "", "setrc #<imm>", "10000010i8*1....",
1342 /* It would be more realistic to let loop_start point to some static
1343 memory that contains an illegal opcode and then give a bus error when
1344 the loop is eventually encountered, but it seems not only simpler,
1345 but also more debugging-friendly to just catch the failure here. */
1346 "if (BUSERROR (RS | RE, maskw))",
1347 " RAISE_EXCEPTION (SIGILL);",
1348 "else {",
1349 " SET_RC (i);",
1350 " loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1351 " CHECK_INSN_PTR (insn_ptr);",
1352 "}",
1353 },
1354
1355 { "", "", "sets", "0000000001011000",
1356 "SET_SR_S (1);",
1357 },
1358
1359 { "", "", "sett", "0000000000011000",
1360 "SET_SR_T (1);",
1361 },
1362
1363 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1364 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1365 },
1366
1367 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1368 "SET_SR_T (R[n] < 0);",
1369 "R[n] <<= 1;",
1370 },
1371
1372 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1373 "SET_SR_T (R[n] & 1);",
1374 "R[n] = R[n] >> 1;",
1375 },
1376
1377 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1378 "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1379 },
1380
1381 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1382 "SET_SR_T (R[n] < 0);",
1383 "R[n] <<= 1;",
1384 },
1385
1386 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1387 "R[n] <<= 2;",
1388 },
1389 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1390 "R[n] <<= 8;",
1391 },
1392 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1393 "R[n] <<= 16;",
1394 },
1395
1396 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1397 "SET_SR_T (R[n] & 1);",
1398 "R[n] = UR[n] >> 1;",
1399 },
1400
1401 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1402 "R[n] = UR[n] >> 2;",
1403 },
1404 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1405 "R[n] = UR[n] >> 8;",
1406 },
1407 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1408 "R[n] = UR[n] >> 16;",
1409 },
1410
1411 { "", "", "sleep", "0000000000011011",
1412 "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1413 },
1414
1415 { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1416 "R[n] = CREG (m);",
1417 },
1418
1419 { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1420 "if (SR_MD)",
1421 " R[n] = SGR; /* priv mode */",
1422 "else",
1423 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1424 },
1425 { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1426 "if (SR_MD)",
1427 " R[n] = DBR; /* priv mode */",
1428 "else",
1429 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1430 },
1431 { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1432 "if (SR_MD)", /* FIXME? */
1433 " R[n] = TBR; /* priv mode */",
1434 "else",
1435 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1436 },
1437 { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1438 "MA (1);",
1439 "R[n] -= 4;",
1440 "WLAT (R[n], CREG (m));",
1441 },
1442 { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1443 "if (SR_MD)",
1444 "{ /* priv mode */",
1445 " MA (1);",
1446 " R[n] -= 4;",
1447 " WLAT (R[n], SGR);",
1448 "}",
1449 "else",
1450 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1451 },
1452 { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1453 "if (SR_MD)",
1454 "{ /* priv mode */",
1455 " MA (1);",
1456 " R[n] -= 4;",
1457 " WLAT (R[n], DBR);",
1458 "}",
1459 "else",
1460 " RAISE_EXCEPTION (SIGILL); /* user mode */",
1461 },
1462
1463 { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1464 "R[n] = SREG (m);",
1465 },
1466 { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1467 "MA (1);",
1468 "R[n] -= 4;",
1469 "WLAT (R[n], SREG (m));",
1470 },
1471
1472 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1473 "R[n] -= R[m];",
1474 },
1475
1476 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1477 "ult = R[n] - T;",
1478 "SET_SR_T (ult > R[n]);",
1479 "R[n] = ult - R[m];",
1480 "SET_SR_T (T || (R[n] > ult));",
1481 },
1482
1483 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1484 "ult = R[n] - R[m];",
1485 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1486 "R[n] = ult;",
1487 },
1488
1489 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1490 "R[n] = ((R[m] & 0xffff0000)",
1491 " | ((R[m] << 8) & 0xff00)",
1492 " | ((R[m] >> 8) & 0x00ff));",
1493 },
1494 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1495 "R[n] = (((R[m] << 16) & 0xffff0000)",
1496 " | ((R[m] >> 16) & 0x00ffff));",
1497 },
1498
1499 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1500 "MA (1);",
1501 "ult = RBAT (R[n]);",
1502 "SET_SR_T (ult == 0);",
1503 "WBAT (R[n],ult|0x80);",
1504 },
1505
1506 { "0", "", "trapa #<imm>", "11000011i8*1....",
1507 "long imm = 0xff & i;",
1508 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1509 "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1510 " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1511 #if 0
1512 "else {",
1513 /* SH-[12] */
1514 " R[15] -= 4;",
1515 " WLAT (R[15], GET_SR ());",
1516 " R[15] -= 4;",
1517 " WLAT (R[15], PH2T (PC + 2));",
1518 #else
1519 "else if (!SR_BL) {",
1520 " SSR = GET_SR ();",
1521 " SPC = PH2T (PC + 2);",
1522 " SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1523 " /* FIXME: EXPEVT = 0x00000160; */",
1524 #endif
1525 " SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1526 "}",
1527 },
1528
1529 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1530 "SET_SR_T ((R[n] & R[m]) == 0);",
1531 },
1532 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1533 "SET_SR_T ((R0 & i) == 0);",
1534 },
1535 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1536 "MA (1);",
1537 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1538 },
1539
1540 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1541 "R0 ^= i;",
1542 },
1543 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1544 "R[n] ^= R[m];",
1545 },
1546 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1547 "MA (1);",
1548 "ult = RBAT (GBR+R0);",
1549 "ult ^= i;",
1550 "WBAT (GBR + R0, ult);",
1551 },
1552
1553 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1554 "R[n] = (((R[n] >> 16) & 0xffff)",
1555 " | ((R[m] << 16) & 0xffff0000));",
1556 },
1557
1558 #if 0
1559 { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1560 "divl (0, R[n], R[m]);",
1561 },
1562 { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1563 "divl (0, R[n], R[m]);",
1564 },
1565 #endif
1566
1567 {0, 0}};
1568
1569 op movsxy_tab[] =
1570 {
1571 /* If this is disabled, the simulator speeds up by about 12% on a
1572 450 MHz PIII - 9% with ACE_FAST.
1573 Maybe we should have separate simulator loops? */
1574 #if 1
1575 { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1576 "MA (1);",
1577 "R[n] -= 2;",
1578 "DSP_R (m) = RSWAT (R[n]) << 16;",
1579 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1580 },
1581 { "", "n", "movs.w @<REG_N>,<DSP_REG_M>", "111101NNMMMM0100",
1582 "MA (1);",
1583 "DSP_R (m) = RSWAT (R[n]) << 16;",
1584 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1585 },
1586 { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1587 "MA (1);",
1588 "DSP_R (m) = RSWAT (R[n]) << 16;",
1589 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1590 "R[n] += 2;",
1591 },
1592 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1593 "MA (1);",
1594 "DSP_R (m) = RSWAT (R[n]) << 16;",
1595 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1596 "R[n] += R[8];",
1597 },
1598 { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1599 "MA (1);",
1600 "R[n] -= 2;",
1601 "DSP_R (m) = RSWAT (R[n]);",
1602 },
1603 { "", "n", "movs.w @<REG_N>,<DSP_GRD_M>", "111101NNGGGG0100",
1604 "MA (1);",
1605 "DSP_R (m) = RSWAT (R[n]);",
1606 },
1607 { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1608 "MA (1);",
1609 "DSP_R (m) = RSWAT (R[n]);",
1610 "R[n] += 2;",
1611 },
1612 { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1613 "MA (1);",
1614 "DSP_R (m) = RSWAT (R[n]);",
1615 "R[n] += R[8];",
1616 },
1617 { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1618 "MA (1);",
1619 "R[n] -= 2;",
1620 "WWAT (R[n], DSP_R (m) >> 16);",
1621 },
1622 { "", "n", "movs.w <DSP_REG_M>,@<REG_N>", "111101NNMMMM0101",
1623 "MA (1);",
1624 "WWAT (R[n], DSP_R (m) >> 16);",
1625 },
1626 { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1627 "MA (1);",
1628 "WWAT (R[n], DSP_R (m) >> 16);",
1629 "R[n] += 2;",
1630 },
1631 { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1632 "MA (1);",
1633 "WWAT (R[n], DSP_R (m) >> 16);",
1634 "R[n] += R[8];",
1635 },
1636 { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1637 "MA (1);",
1638 "R[n] -= 2;",
1639 "WWAT (R[n], SEXT (DSP_R (m)));",
1640 },
1641 { "", "n", "movs.w <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0101",
1642 "MA (1);",
1643 "WWAT (R[n], SEXT (DSP_R (m)));",
1644 },
1645 { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1646 "MA (1);",
1647 "WWAT (R[n], SEXT (DSP_R (m)));",
1648 "R[n] += 2;",
1649 },
1650 { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1651 "MA (1);",
1652 "WWAT (R[n], SEXT (DSP_R (m)));",
1653 "R[n] += R[8];",
1654 },
1655 { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1656 "MA (1);",
1657 "R[n] -= 4;",
1658 "DSP_R (m) = RLAT (R[n]);",
1659 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1660 },
1661 { "", "n", "movs.l @<REG_N>,<DSP_REG_M>", "111101NNMMMM0110",
1662 "MA (1);",
1663 "DSP_R (m) = RLAT (R[n]);",
1664 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1665 },
1666 { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1667 "MA (1);",
1668 "DSP_R (m) = RLAT (R[n]);",
1669 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1670 "R[n] += 4;",
1671 },
1672 { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1673 "MA (1);",
1674 "DSP_R (m) = RLAT (R[n]);",
1675 "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1676 "R[n] += R[8];",
1677 },
1678 { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1679 "MA (1);",
1680 "R[n] -= 4;",
1681 "WLAT (R[n], DSP_R (m));",
1682 },
1683 { "", "n", "movs.l <DSP_REG_M>,@<REG_N>", "111101NNMMMM0111",
1684 "MA (1);",
1685 "WLAT (R[n], DSP_R (m));",
1686 },
1687 { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1688 "MA (1);",
1689 "WLAT (R[n], DSP_R (m));",
1690 "R[n] += 4;",
1691 },
1692 { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1693 "MA (1);",
1694 "WLAT (R[n], DSP_R (m));",
1695 "R[n] += R[8];",
1696 },
1697 { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1698 "MA (1);",
1699 "R[n] -= 4;",
1700 "WLAT (R[n], SEXT (DSP_R (m)));",
1701 },
1702 { "", "n", "movs.l <DSP_GRD_M>,@<REG_N>", "111101NNGGGG0111",
1703 "MA (1);",
1704 "WLAT (R[n], SEXT (DSP_R (m)));",
1705 },
1706 { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1707 "MA (1);",
1708 "WLAT (R[n], SEXT (DSP_R (m)));",
1709 "R[n] += 4;",
1710 },
1711 { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1712 "MA (1);",
1713 "WLAT (R[n], SEXT (DSP_R (m)));",
1714 "R[n] += R[8];",
1715 },
1716 { "", "n", "movx.w @<REG_xy>,<DSP_XY>", "111100xyXY0001??",
1717 "DSP_R (m) = RSWAT (R[n]) << 16;",
1718 "if (iword & 3)",
1719 " {",
1720 " iword &= 0xfd53; goto top;",
1721 " }",
1722 },
1723 { "", "n", "movx.l @<REG_xy>,<DSP_XY>", "111100xyXY010100",
1724 "DSP_R (m) = RLAT (R[n]);",
1725 },
1726 { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1727 "DSP_R (m) = RSWAT (R[n]) << 16;",
1728 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1729 "if (iword & 3)",
1730 " {",
1731 " iword &= 0xfd53; goto top;",
1732 " }",
1733 },
1734 { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1735 "DSP_R (m) = RLAT (R[n]);",
1736 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1737 },
1738 { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1739 "DSP_R (m) = RSWAT (R[n]) << 16;",
1740 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1741 "if (iword & 3)",
1742 " {",
1743 " iword &= 0xfd53; goto top;",
1744 " }",
1745 },
1746 { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1747 "DSP_R (m) = RLAT (R[n]);",
1748 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1749 },
1750 { "", "n", "movx.w <DSP_Ax>,@<REG_xy>", "111100xyax1001??",
1751 "WWAT (R[n], DSP_R (m) >> 16);",
1752 "if (iword & 3)",
1753 " {",
1754 " iword &= 0xfd53; goto top;",
1755 " }",
1756 },
1757 { "", "n", "movx.l <DSP_Ax>,@<REG_xy>", "111100xyax110100",
1758 "WLAT (R[n], DSP_R (m));",
1759 },
1760 { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1761 "WWAT (R[n], DSP_R (m) >> 16);",
1762 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1763 "if (iword & 3)",
1764 " {",
1765 " iword &= 0xfd53; goto top;",
1766 " }",
1767 },
1768 { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1769 "WLAT (R[n], DSP_R (m));",
1770 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1771 },
1772 { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1773 "WWAT (R[n], DSP_R (m) >> 16);",
1774 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1775 "if (iword & 3)",
1776 " {",
1777 " iword &= 0xfd53; goto top;",
1778 " }",
1779 },
1780 { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1781 "WLAT (R[n], DSP_R (m));",
1782 "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1783 },
1784 { "", "n", "movy.w @<REG_yx>,<DSP_YX>", "111100yxYX000001",
1785 "DSP_R (m) = RSWAT (R[n]) << 16;",
1786 },
1787 { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1788 "DSP_R (m) = RSWAT (R[n]) << 16;",
1789 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1790 },
1791 { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1792 "DSP_R (m) = RSWAT (R[n]) << 16;",
1793 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1794 },
1795 { "", "n", "movy.w <DSP_Ay>,@<REG_yx>", "111100yxAY010001",
1796 "WWAT (R[n], DSP_R (m) >> 16);",
1797 },
1798 { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1799 "WWAT (R[n], DSP_R (m) >> 16);",
1800 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1801 },
1802 { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1803 "WWAT (R[n], DSP_R (m) >> 16);",
1804 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1805 },
1806 { "", "n", "movy.l @<REG_yx>,<DSP_YX>", "111100yxYX100001",
1807 "DSP_R (m) = RLAT (R[n]);",
1808 },
1809 { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1810 "DSP_R (m) = RLAT (R[n]);",
1811 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1812 },
1813 { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1814 "DSP_R (m) = RLAT (R[n]);",
1815 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1816 },
1817 { "", "n", "movy.l <DSP_Ay>,@<REG_yx>", "111100yxAY110001",
1818 "WLAT (R[n], DSP_R (m));",
1819 },
1820 { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1821 "WLAT (R[n], DSP_R (m));",
1822 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1823 },
1824 { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1825 "WLAT (R[n], DSP_R (m));",
1826 "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1827 },
1828 { "", "", "nopx nopy", "1111000000000000",
1829 "/* nop */",
1830 },
1831 { "", "", "ppi", "1111100000000000",
1832 "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1833 "ppi_insn (RIAT (nip));",
1834 "SET_NIP (nip + 2);",
1835 "iword &= 0xf7ff; goto top;",
1836 },
1837 #endif
1838 {0, 0}};
1839
1840 op ppi_tab[] =
1841 {
1842 { "","", "pshl #<imm>,dz", "00000iiim16.zzzz",
1843 "int Sz = DSP_R (z) & 0xffff0000;",
1844 "",
1845 "if (i <= 16)",
1846 " res = Sz << i;",
1847 "else if (i >= 128 - 16)",
1848 " res = (unsigned) Sz >> 128 - i; /* no sign extension */",
1849 "else",
1850 " {",
1851 " RAISE_EXCEPTION (SIGILL);",
1852 " return;",
1853 " }",
1854 "res &= 0xffff0000;",
1855 "res_grd = 0;",
1856 "goto logical;",
1857 },
1858 { "","", "psha #<imm>,dz", "00010iiim32.zzzz",
1859 "int Sz = DSP_R (z);",
1860 "int Sz_grd = GET_DSP_GRD (z);",
1861 "",
1862 "if (i <= 32)",
1863 " {",
1864 " if (i == 32)",
1865 " {",
1866 " res = 0;",
1867 " res_grd = Sz;",
1868 " }",
1869 " else",
1870 " {",
1871 " res = Sz << i;",
1872 " res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1873 " }",
1874 " res_grd = SEXT (res_grd);",
1875 " carry = res_grd & 1;",
1876 " }",
1877 "else if (i >= 96)",
1878 " {",
1879 " i = 128 - i;",
1880 " if (i == 32)",
1881 " {",
1882 " res_grd = SIGN32 (Sz_grd);",
1883 " res = Sz_grd;",
1884 " }",
1885 " else",
1886 " {",
1887 " res = Sz >> i | Sz_grd << 32 - i;",
1888 " res_grd = Sz_grd >> i;",
1889 " }",
1890 " carry = Sz >> (i - 1) & 1;",
1891 " }",
1892 "else",
1893 " {",
1894 " RAISE_EXCEPTION (SIGILL);",
1895 " return;",
1896 " }",
1897 "COMPUTE_OVERFLOW;",
1898 "greater_equal = 0;",
1899 },
1900 { "","", "pmuls Se,Sf,Dg", "0100eeffxxyygguu",
1901 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1902 "if (res == 0x80000000)",
1903 " res = 0x7fffffff;",
1904 "DSP_R (g) = res;",
1905 "DSP_GRD (g) = SIGN32 (res);",
1906 "return;",
1907 },
1908 { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg", "0110eeffxxyygguu",
1909 "int Sx = DSP_R (x);",
1910 "int Sx_grd = GET_DSP_GRD (x);",
1911 "int Sy = DSP_R (y);",
1912 "int Sy_grd = SIGN32 (Sy);",
1913 "",
1914 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1915 "if (res == 0x80000000)",
1916 " res = 0x7fffffff;",
1917 "DSP_R (g) = res;",
1918 "DSP_GRD (g) = SIGN32 (res);",
1919 "",
1920 "z = u;",
1921 "res = Sx - Sy;",
1922 "carry = (unsigned) res > (unsigned) Sx;",
1923 "res_grd = Sx_grd - Sy_grd - carry;",
1924 "COMPUTE_OVERFLOW;",
1925 "ADD_SUB_GE;",
1926 },
1927 { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg", "0111eeffxxyygguu",
1928 "int Sx = DSP_R (x);",
1929 "int Sx_grd = GET_DSP_GRD (x);",
1930 "int Sy = DSP_R (y);",
1931 "int Sy_grd = SIGN32 (Sy);",
1932 "",
1933 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1934 "if (res == 0x80000000)",
1935 " res = 0x7fffffff;",
1936 "DSP_R (g) = res;",
1937 "DSP_GRD (g) = SIGN32 (res);",
1938 "",
1939 "z = u;",
1940 "res = Sx + Sy;",
1941 "carry = (unsigned) res < (unsigned) Sx;",
1942 "res_grd = Sx_grd + Sy_grd + carry;",
1943 "COMPUTE_OVERFLOW;",
1944 },
1945 { "","", "psubc Sx,Sy,Dz", "10100000xxyyzzzz",
1946 "int Sx = DSP_R (x);",
1947 "int Sx_grd = GET_DSP_GRD (x);",
1948 "int Sy = DSP_R (y);",
1949 "int Sy_grd = SIGN32 (Sy);",
1950 "",
1951 "res = Sx - Sy - (DSR & 1);",
1952 "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1953 "res_grd = Sx_grd + Sy_grd + carry;",
1954 "COMPUTE_OVERFLOW;",
1955 "ADD_SUB_GE;",
1956 "DSR &= ~0xf1;\n",
1957 "if (res || res_grd)\n",
1958 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1959 "else\n",
1960 " DSR |= DSR_MASK_Z | overflow;\n",
1961 "DSR |= carry;\n",
1962 "goto assign_z;\n",
1963 },
1964 { "","", "paddc Sx,Sy,Dz", "10110000xxyyzzzz",
1965 "int Sx = DSP_R (x);",
1966 "int Sx_grd = GET_DSP_GRD (x);",
1967 "int Sy = DSP_R (y);",
1968 "int Sy_grd = SIGN32 (Sy);",
1969 "",
1970 "res = Sx + Sy + (DSR & 1);",
1971 "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1972 "res_grd = Sx_grd + Sy_grd + carry;",
1973 "COMPUTE_OVERFLOW;",
1974 "ADD_SUB_GE;",
1975 "DSR &= ~0xf1;\n",
1976 "if (res || res_grd)\n",
1977 " DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1978 "else\n",
1979 " DSR |= DSR_MASK_Z | overflow;\n",
1980 "DSR |= carry;\n",
1981 "goto assign_z;\n",
1982 },
1983 { "","", "pcmp Sx,Sy", "10000100xxyyzzzz",
1984 "int Sx = DSP_R (x);",
1985 "int Sx_grd = GET_DSP_GRD (x);",
1986 "int Sy = DSP_R (y);",
1987 "int Sy_grd = SIGN32 (Sy);",
1988 "",
1989 "z = 17; /* Ignore result. */",
1990 "res = Sx - Sy;",
1991 "carry = (unsigned) res > (unsigned) Sx;",
1992 "res_grd = Sx_grd - Sy_grd - carry;",
1993 "COMPUTE_OVERFLOW;",
1994 "ADD_SUB_GE;",
1995 },
1996 { "","", "pwsb Sx,Sy,Dz", "10100100xxyyzzzz",
1997 },
1998 { "","", "pwad Sx,Sy,Dz", "10110100xxyyzzzz",
1999 },
2000 { "","", "(if cc) pabs Sx,Dz", "100010ccxx01zzzz",
2001 "/* FIXME: duplicate code pabs. */",
2002 "res = DSP_R (x);",
2003 "res_grd = GET_DSP_GRD (x);",
2004 "if (res >= 0)",
2005 " carry = 0;",
2006 "else",
2007 " {",
2008 " res = -res;",
2009 " carry = (res != 0); /* The manual has a bug here. */",
2010 " res_grd = -res_grd - carry;",
2011 " }",
2012 "COMPUTE_OVERFLOW;",
2013 "/* ??? The re-computing of overflow after",
2014 " saturation processing is specific to pabs. */",
2015 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2016 "ADD_SUB_GE;",
2017 },
2018 { "","", "pabs Sx,Dz", "10001000xx..zzzz",
2019 "res = DSP_R (x);",
2020 "res_grd = GET_DSP_GRD (x);",
2021 "if (res >= 0)",
2022 " carry = 0;",
2023 "else",
2024 " {",
2025 " res = -res;",
2026 " carry = (res != 0); /* The manual has a bug here. */",
2027 " res_grd = -res_grd - carry;",
2028 " }",
2029 "COMPUTE_OVERFLOW;",
2030 "/* ??? The re-computing of overflow after",
2031 " saturation processing is specific to pabs. */",
2032 "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2033 "ADD_SUB_GE;",
2034 },
2035
2036 { "","", "(if cc) prnd Sx,Dz", "100110ccxx01zzzz",
2037 "/* FIXME: duplicate code prnd. */",
2038 "int Sx = DSP_R (x);",
2039 "int Sx_grd = GET_DSP_GRD (x);",
2040 "",
2041 "res = (Sx + 0x8000) & 0xffff0000;",
2042 "carry = (unsigned) res < (unsigned) Sx;",
2043 "res_grd = Sx_grd + carry;",
2044 "COMPUTE_OVERFLOW;",
2045 "ADD_SUB_GE;",
2046 },
2047 { "","", "prnd Sx,Dz", "10011000xx..zzzz",
2048 "int Sx = DSP_R (x);",
2049 "int Sx_grd = GET_DSP_GRD (x);",
2050 "",
2051 "res = (Sx + 0x8000) & 0xffff0000;",
2052 "carry = (unsigned) res < (unsigned) Sx;",
2053 "res_grd = Sx_grd + carry;",
2054 "COMPUTE_OVERFLOW;",
2055 "ADD_SUB_GE;",
2056 },
2057
2058 { "","", "(if cc) pabs Sy,Dz", "101010cc01yyzzzz",
2059 "/* FIXME: duplicate code pabs. */",
2060 "res = DSP_R (y);",
2061 "res_grd = 0;",
2062 "overflow = 0;",
2063 "greater_equal = DSR_MASK_G;",
2064 "if (res >= 0)",
2065 " carry = 0;",
2066 "else",
2067 " {",
2068 " res = -res;",
2069 " carry = 1;",
2070 " if (res < 0)",
2071 " {",
2072 " if (S)",
2073 " res = 0x7fffffff;",
2074 " else",
2075 " {",
2076 " overflow = DSR_MASK_V;",
2077 " greater_equal = 0;",
2078 " }",
2079 " }",
2080 " }",
2081 },
2082 { "","", "pabs Sy,Dz", "10101000..yyzzzz",
2083 "res = DSP_R (y);",
2084 "res_grd = 0;",
2085 "overflow = 0;",
2086 "greater_equal = DSR_MASK_G;",
2087 "if (res >= 0)",
2088 " carry = 0;",
2089 "else",
2090 " {",
2091 " res = -res;",
2092 " carry = 1;",
2093 " if (res < 0)",
2094 " {",
2095 " if (S)",
2096 " res = 0x7fffffff;",
2097 " else",
2098 " {",
2099 " overflow = DSR_MASK_V;",
2100 " greater_equal = 0;",
2101 " }",
2102 " }",
2103 " }",
2104 },
2105 { "","", "(if cc) prnd Sy,Dz", "101110cc01yyzzzz",
2106 "/* FIXME: duplicate code prnd. */",
2107 "int Sy = DSP_R (y);",
2108 "int Sy_grd = SIGN32 (Sy);",
2109 "",
2110 "res = (Sy + 0x8000) & 0xffff0000;",
2111 "carry = (unsigned) res < (unsigned) Sy;",
2112 "res_grd = Sy_grd + carry;",
2113 "COMPUTE_OVERFLOW;",
2114 "ADD_SUB_GE;",
2115 },
2116 { "","", "prnd Sy,Dz", "10111000..yyzzzz",
2117 "int Sy = DSP_R (y);",
2118 "int Sy_grd = SIGN32 (Sy);",
2119 "",
2120 "res = (Sy + 0x8000) & 0xffff0000;",
2121 "carry = (unsigned) res < (unsigned) Sy;",
2122 "res_grd = Sy_grd + carry;",
2123 "COMPUTE_OVERFLOW;",
2124 "ADD_SUB_GE;",
2125 },
2126 { "","", "(if cc) pshl Sx,Sy,Dz", "100000ccxxyyzzzz",
2127 "int Sx = DSP_R (x) & 0xffff0000;",
2128 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2129 "",
2130 "if (Sy <= 16)",
2131 " res = Sx << Sy;",
2132 "else if (Sy >= 128 - 16)",
2133 " res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2134 "else",
2135 " {",
2136 " RAISE_EXCEPTION (SIGILL);",
2137 " return;",
2138 " }",
2139 "goto cond_logical;",
2140 },
2141 { "","", "(if cc) psha Sx,Sy,Dz", "100100ccxxyyzzzz",
2142 "int Sx = DSP_R (x);",
2143 "int Sx_grd = GET_DSP_GRD (x);",
2144 "int Sy = DSP_R (y) >> 16 & 0x7f;",
2145 "",
2146 "if (Sy <= 32)",
2147 " {",
2148 " if (Sy == 32)",
2149 " {",
2150 " res = 0;",
2151 " res_grd = Sx;",
2152 " }",
2153 " else",
2154 " {",
2155 " res = Sx << Sy;",
2156 " res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2157 " }",
2158 " res_grd = SEXT (res_grd);",
2159 " carry = res_grd & 1;",
2160 " }",
2161 "else if (Sy >= 96)",
2162 " {",
2163 " Sy = 128 - Sy;",
2164 " if (Sy == 32)",
2165 " {",
2166 " res_grd = SIGN32 (Sx_grd);",
2167 " res = Sx_grd;",
2168 " }",
2169 " else",
2170 " {",
2171 " res = Sx >> Sy | Sx_grd << 32 - Sy;",
2172 " res_grd = Sx_grd >> Sy;",
2173 " }",
2174 " carry = Sx >> (Sy - 1) & 1;",
2175 " }",
2176 "else",
2177 " {",
2178 " RAISE_EXCEPTION (SIGILL);",
2179 " return;",
2180 " }",
2181 "COMPUTE_OVERFLOW;",
2182 "greater_equal = 0;",
2183 },
2184 { "","", "(if cc) psub Sx,Sy,Dz", "101000ccxxyyzzzz",
2185 "int Sx = DSP_R (x);",
2186 "int Sx_grd = GET_DSP_GRD (x);",
2187 "int Sy = DSP_R (y);",
2188 "int Sy_grd = SIGN32 (Sy);",
2189 "",
2190 "res = Sx - Sy;",
2191 "carry = (unsigned) res > (unsigned) Sx;",
2192 "res_grd = Sx_grd - Sy_grd - carry;",
2193 "COMPUTE_OVERFLOW;",
2194 "ADD_SUB_GE;",
2195 },
2196 { "","", "(if cc) psub Sy,Sx,Dz", "100001ccxxyyzzzz",
2197 "int Sx = DSP_R (x);",
2198 "int Sx_grd = GET_DSP_GRD (x);",
2199 "int Sy = DSP_R (y);",
2200 "int Sy_grd = SIGN32 (Sy);",
2201 "",
2202 "res = Sy - Sx;",
2203 "carry = (unsigned) res > (unsigned) Sy;",
2204 "res_grd = Sy_grd - Sx_grd - carry;",
2205 "COMPUTE_OVERFLOW;",
2206 "ADD_SUB_GE;",
2207 },
2208 { "","", "(if cc) padd Sx,Sy,Dz", "101100ccxxyyzzzz",
2209 "int Sx = DSP_R (x);",
2210 "int Sx_grd = GET_DSP_GRD (x);",
2211 "int Sy = DSP_R (y);",
2212 "int Sy_grd = SIGN32 (Sy);",
2213 "",
2214 "res = Sx + Sy;",
2215 "carry = (unsigned) res < (unsigned) Sx;",
2216 "res_grd = Sx_grd + Sy_grd + carry;",
2217 "COMPUTE_OVERFLOW;",
2218 "ADD_SUB_GE;",
2219 },
2220 { "","", "(if cc) pand Sx,Sy,Dz", "100101ccxxyyzzzz",
2221 "res = DSP_R (x) & DSP_R (y);",
2222 "cond_logical:",
2223 "res &= 0xffff0000;",
2224 "res_grd = 0;",
2225 "if (iword & 0x200)\n",
2226 " goto assign_z;\n",
2227 "logical:",
2228 "carry = 0;",
2229 "overflow = 0;",
2230 "greater_equal = 0;",
2231 "DSR &= ~0xf1;\n",
2232 "if (res)\n",
2233 " DSR |= res >> 26 & DSR_MASK_N;\n",
2234 "else\n",
2235 " DSR |= DSR_MASK_Z;\n",
2236 "goto assign_dc;\n",
2237 },
2238 { "","", "(if cc) pxor Sx,Sy,Dz", "101001ccxxyyzzzz",
2239 "res = DSP_R (x) ^ DSP_R (y);",
2240 "goto cond_logical;",
2241 },
2242 { "","", "(if cc) por Sx,Sy,Dz", "101101ccxxyyzzzz",
2243 "res = DSP_R (x) | DSP_R (y);",
2244 "goto cond_logical;",
2245 },
2246 { "","", "(if cc) pdec Sx,Dz", "100010ccxx..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) pinc Sx,Dz", "100110ccxx..zzzz",
2258 "int Sx = DSP_R (x);",
2259 "int Sx_grd = GET_DSP_GRD (x);",
2260 "",
2261 "res = Sx + 0x10000;",
2262 "carry = res < Sx;",
2263 "res_grd = Sx_grd + carry;",
2264 "COMPUTE_OVERFLOW;",
2265 "ADD_SUB_GE;",
2266 "res &= 0xffff0000;",
2267 },
2268 { "","", "(if cc) pdec Sy,Dz", "101010cc..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) pinc Sy,Dz", "101110cc..yyzzzz",
2280 "int Sy = DSP_R (y);",
2281 "int Sy_grd = SIGN32 (Sy);",
2282 "",
2283 "res = Sy + 0x10000;",
2284 "carry = res < Sy;",
2285 "res_grd = Sy_grd + carry;",
2286 "COMPUTE_OVERFLOW;",
2287 "ADD_SUB_GE;",
2288 "res &= 0xffff0000;",
2289 },
2290 { "","", "(if cc) pclr Dz", "100011cc....zzzz",
2291 "res = 0;",
2292 "res_grd = 0;",
2293 "carry = 0;",
2294 "overflow = 0;",
2295 "greater_equal = 1;",
2296 },
2297 { "","", "pclr Du pmuls Se,Sf,Dg", "0100eeff0001gguu",
2298 "/* Do multiply. */",
2299 "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2300 "if (res == 0x80000000)",
2301 " res = 0x7fffffff;",
2302 "DSP_R (g) = res;",
2303 "DSP_GRD (g) = SIGN32 (res);",
2304 "/* FIXME: update DSR based on results of multiply! */",
2305 "",
2306 "/* Do clr. */",
2307 "z = u;",
2308 "res = 0;",
2309 "res_grd = 0;",
2310 "goto assign_z;",
2311 },
2312 { "","", "(if cc) pdmsb Sx,Dz", "100111ccxx..zzzz",
2313 "unsigned Sx = DSP_R (x);",
2314 "int Sx_grd = GET_DSP_GRD (x);",
2315 "int i = 16;",
2316 "",
2317 "if (Sx_grd < 0)",
2318 " {",
2319 " Sx_grd = ~Sx_grd;",
2320 " Sx = ~Sx;",
2321 " }",
2322 "if (Sx_grd)",
2323 " {",
2324 " Sx = Sx_grd;",
2325 " res = -2;",
2326 " }",
2327 "else if (Sx)",
2328 " res = 30;",
2329 "else",
2330 " res = 31;",
2331 "do",
2332 " {",
2333 " if (Sx & ~0 << i)",
2334 " {",
2335 " res -= i;",
2336 " Sx >>= i;",
2337 " }",
2338 " }",
2339 "while (i >>= 1);",
2340 "res <<= 16;",
2341 "res_grd = SIGN32 (res);",
2342 "carry = 0;",
2343 "overflow = 0;",
2344 "ADD_SUB_GE;",
2345 },
2346 { "","", "(if cc) pdmsb Sy,Dz", "101111cc..yyzzzz",
2347 "unsigned Sy = DSP_R (y);",
2348 "int i;",
2349 "",
2350 "if (Sy < 0)",
2351 " Sy = ~Sy;",
2352 "Sy <<= 1;",
2353 "res = 31;",
2354 "do",
2355 " {",
2356 " if (Sy & ~0 << i)",
2357 " {",
2358 " res -= i;",
2359 " Sy >>= i;",
2360 " }",
2361 " }",
2362 "while (i >>= 1);",
2363 "res <<= 16;",
2364 "res_grd = SIGN32 (res);",
2365 "carry = 0;",
2366 "overflow = 0;",
2367 "ADD_SUB_GE;",
2368 },
2369 { "","", "(if cc) pneg Sx,Dz", "110010ccxx..zzzz",
2370 "int Sx = DSP_R (x);",
2371 "int Sx_grd = GET_DSP_GRD (x);",
2372 "",
2373 "res = 0 - Sx;",
2374 "carry = res != 0;",
2375 "res_grd = 0 - Sx_grd - carry;",
2376 "COMPUTE_OVERFLOW;",
2377 "ADD_SUB_GE;",
2378 },
2379 { "","", "(if cc) pcopy Sx,Dz", "110110ccxx..zzzz",
2380 "res = DSP_R (x);",
2381 "res_grd = GET_DSP_GRD (x);",
2382 "carry = 0;",
2383 "COMPUTE_OVERFLOW;",
2384 "ADD_SUB_GE;",
2385 },
2386 { "","", "(if cc) pneg Sy,Dz", "111010cc..yyzzzz",
2387 "int Sy = DSP_R (y);",
2388 "int Sy_grd = SIGN32 (Sy);",
2389 "",
2390 "res = 0 - Sy;",
2391 "carry = res != 0;",
2392 "res_grd = 0 - Sy_grd - carry;",
2393 "COMPUTE_OVERFLOW;",
2394 "ADD_SUB_GE;",
2395 },
2396 { "","", "(if cc) pcopy Sy,Dz", "111110cc..yyzzzz",
2397 "res = DSP_R (y);",
2398 "res_grd = SIGN32 (res);",
2399 "carry = 0;",
2400 "COMPUTE_OVERFLOW;",
2401 "ADD_SUB_GE;",
2402 },
2403 { "","", "(if cc) psts MACH,Dz", "110011cc....zzzz",
2404 "res = MACH;",
2405 "res_grd = SIGN32 (res);",
2406 "goto assign_z;",
2407 },
2408 { "","", "(if cc) psts MACL,Dz", "110111cc....zzzz",
2409 "res = MACL;",
2410 "res_grd = SIGN32 (res);",
2411 "goto assign_z;",
2412 },
2413 { "","", "(if cc) plds Dz,MACH", "111011cc....zzzz",
2414 "if (0xa05f >> z & 1)",
2415 " RAISE_EXCEPTION (SIGILL);",
2416 "else",
2417 " MACH = DSP_R (z);",
2418 "return;",
2419 },
2420 { "","", "(if cc) plds Dz,MACL", "111111cc....zzzz",
2421 "if (0xa05f >> z & 1)",
2422 " RAISE_EXCEPTION (SIGILL);",
2423 "else",
2424 " MACL = DSP_R (z) = res;",
2425 "return;",
2426 },
2427 /* sh4a */
2428 { "","", "(if cc) pswap Sx,Dz", "100111ccxx01zzzz",
2429 "int Sx = DSP_R (x);",
2430 "",
2431 "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2432 "res_grd = GET_DSP_GRD (x);",
2433 "carry = 0;",
2434 "overflow = 0;",
2435 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2436 },
2437 /* sh4a */
2438 { "","", "(if cc) pswap Sy,Dz", "101111cc01yyzzzz",
2439 "int Sy = DSP_R (y);",
2440 "",
2441 "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2442 "res_grd = SIGN32 (Sy);",
2443 "carry = 0;",
2444 "overflow = 0;",
2445 "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2446 },
2447
2448 {0, 0}
2449 };
2450
2451 /* Tables of things to put into enums for sh-opc.h */
2452 static char *nibble_type_list[] =
2453 {
2454 "HEX_0",
2455 "HEX_1",
2456 "HEX_2",
2457 "HEX_3",
2458 "HEX_4",
2459 "HEX_5",
2460 "HEX_6",
2461 "HEX_7",
2462 "HEX_8",
2463 "HEX_9",
2464 "HEX_A",
2465 "HEX_B",
2466 "HEX_C",
2467 "HEX_D",
2468 "HEX_E",
2469 "HEX_F",
2470 "REG_N",
2471 "REG_M",
2472 "BRANCH_12",
2473 "BRANCH_8",
2474 "DISP_8",
2475 "DISP_4",
2476 "IMM_4",
2477 "IMM_4BY2",
2478 "IMM_4BY4",
2479 "PCRELIMM_8BY2",
2480 "PCRELIMM_8BY4",
2481 "IMM_8",
2482 "IMM_8BY2",
2483 "IMM_8BY4",
2484 0
2485 };
2486 static
2487 char *arg_type_list[] =
2488 {
2489 "A_END",
2490 "A_BDISP12",
2491 "A_BDISP8",
2492 "A_DEC_M",
2493 "A_DEC_N",
2494 "A_DISP_GBR",
2495 "A_DISP_PC",
2496 "A_DISP_REG_M",
2497 "A_DISP_REG_N",
2498 "A_GBR",
2499 "A_IMM",
2500 "A_INC_M",
2501 "A_INC_N",
2502 "A_IND_M",
2503 "A_IND_N",
2504 "A_IND_R0_REG_M",
2505 "A_IND_R0_REG_N",
2506 "A_MACH",
2507 "A_MACL",
2508 "A_PR",
2509 "A_R0",
2510 "A_R0_GBR",
2511 "A_REG_M",
2512 "A_REG_N",
2513 "A_SR",
2514 "A_VBR",
2515 "A_SSR",
2516 "A_SPC",
2517 0,
2518 };
2519
2520 static void
2521 make_enum_list (name, s)
2522 char *name;
2523 char **s;
2524 {
2525 int i = 1;
2526 printf ("typedef enum {\n");
2527 while (*s)
2528 {
2529 printf ("\t%s,\n", *s);
2530 s++;
2531 i++;
2532 }
2533 printf ("} %s;\n", name);
2534 }
2535
2536 static int
2537 qfunc (a, b)
2538 op *a;
2539 op *b;
2540 {
2541 char bufa[9];
2542 char bufb[9];
2543 int diff;
2544
2545 memcpy (bufa, a->code, 4);
2546 memcpy (bufa + 4, a->code + 12, 4);
2547 bufa[8] = 0;
2548
2549 memcpy (bufb, b->code, 4);
2550 memcpy (bufb + 4, b->code + 12, 4);
2551 bufb[8] = 0;
2552 diff = strcmp (bufa, bufb);
2553 /* Stabilize the sort, so that later entries can override more general
2554 preceding entries. */
2555 return diff ? diff : a - b;
2556 }
2557
2558 static void
2559 sorttab ()
2560 {
2561 op *p = tab;
2562 int len = 0;
2563
2564 while (p->name)
2565 {
2566 p++;
2567 len++;
2568 }
2569 qsort (tab, len, sizeof (*p), qfunc);
2570 }
2571
2572 static void
2573 gengastab ()
2574 {
2575 op *p;
2576 sorttab ();
2577 for (p = tab; p->name; p++)
2578 {
2579 printf ("%s %-30s\n", p->code, p->name);
2580 }
2581 }
2582
2583 static unsigned short table[1 << 16];
2584
2585 static int warn_conflicts = 0;
2586
2587 static void
2588 conflict_warn (val, i)
2589 int val;
2590 int i;
2591 {
2592 int ix, key;
2593 int j = table[val];
2594
2595 fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2596 val, i, table[val]);
2597
2598 for (ix = sizeof (tab) / sizeof (tab[0]); ix >= 0; ix--)
2599 if (tab[ix].index == i || tab[ix].index == j)
2600 {
2601 key = ((tab[ix].code[0] - '0') << 3) +
2602 ((tab[ix].code[1] - '0') << 2) +
2603 ((tab[ix].code[2] - '0') << 1) +
2604 ((tab[ix].code[3] - '0'));
2605
2606 if (val >> 12 == key)
2607 fprintf (stderr, " %s -- %s\n", tab[ix].code, tab[ix].name);
2608 }
2609
2610 for (ix = sizeof (movsxy_tab) / sizeof (movsxy_tab[0]); ix >= 0; ix--)
2611 if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
2612 {
2613 key = ((movsxy_tab[ix].code[0] - '0') << 3) +
2614 ((movsxy_tab[ix].code[1] - '0') << 2) +
2615 ((movsxy_tab[ix].code[2] - '0') << 1) +
2616 ((movsxy_tab[ix].code[3] - '0'));
2617
2618 if (val >> 12 == key)
2619 fprintf (stderr, " %s -- %s\n",
2620 movsxy_tab[ix].code, movsxy_tab[ix].name);
2621 }
2622
2623 for (ix = sizeof (ppi_tab) / sizeof (ppi_tab[0]); ix >= 0; ix--)
2624 if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
2625 {
2626 key = ((ppi_tab[ix].code[0] - '0') << 3) +
2627 ((ppi_tab[ix].code[1] - '0') << 2) +
2628 ((ppi_tab[ix].code[2] - '0') << 1) +
2629 ((ppi_tab[ix].code[3] - '0'));
2630
2631 if (val >> 12 == key)
2632 fprintf (stderr, " %s -- %s\n",
2633 ppi_tab[ix].code, ppi_tab[ix].name);
2634 }
2635 }
2636
2637 /* Take an opcode, expand all varying fields in it out and fill all the
2638 right entries in 'table' with the opcode index. */
2639
2640 static void
2641 expand_opcode (val, i, s)
2642 int val;
2643 int i;
2644 char *s;
2645 {
2646 if (*s == 0)
2647 {
2648 if (warn_conflicts && table[val] != 0)
2649 conflict_warn (val, i);
2650 table[val] = i;
2651 }
2652 else
2653 {
2654 int j = 0, m = 0;
2655
2656 switch (s[0])
2657 {
2658 default:
2659 fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
2660 exit (1);
2661 case '0':
2662 case '1':
2663 /* Consume an arbitrary number of ones and zeros. */
2664 do {
2665 j = (j << 1) + (s[m++] - '0');
2666 } while (s[m] == '0' || s[m] == '1');
2667 expand_opcode ((val << m) | j, i, s + m);
2668 break;
2669 case 'N': /* NN -- four-way fork */
2670 for (j = 0; j < 4; j++)
2671 expand_opcode ((val << 2) | j, i, s + 2);
2672 break;
2673 case 'x': /* xx or xy -- two-way or four-way fork */
2674 for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1))
2675 expand_opcode ((val << 2) | j, i, s + 2);
2676 break;
2677 case 'y': /* yy or yx -- two-way or four-way fork */
2678 for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++)
2679 expand_opcode ((val << 2) | j, i, s + 2);
2680 break;
2681 case '?': /* Seven-way "wildcard" fork for movxy */
2682 expand_opcode ((val << 2), i, s + 2);
2683 for (j = 1; j < 4; j++)
2684 {
2685 expand_opcode ((val << 2) | j, i, s + 2);
2686 expand_opcode ((val << 2) | (j + 16), i, s + 2);
2687 }
2688 break;
2689 case 'i': /* eg. "i8*1" */
2690 case '.': /* "...." is a wildcard */
2691 case 'n':
2692 case 'm':
2693 /* nnnn, mmmm, i#*#, .... -- 16-way fork. */
2694 for (j = 0; j < 16; j++)
2695 expand_opcode ((val << 4) | j, i, s + 4);
2696 break;
2697 case 'e':
2698 /* eeee -- even numbered register:
2699 8 way fork. */
2700 for (j = 0; j < 15; j += 2)
2701 expand_opcode ((val << 4) | j, i, s + 4);
2702 break;
2703 case 'M':
2704 /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2705 MMMM -- 10-way fork */
2706 expand_opcode ((val << 4) | 5, i, s + 4);
2707 for (j = 7; j < 16; j++)
2708 expand_opcode ((val << 4) | j, i, s + 4);
2709 break;
2710 case 'G':
2711 /* A1G, A0G:
2712 GGGG -- two-way fork */
2713 for (j = 13; j <= 15; j +=2)
2714 expand_opcode ((val << 4) | j, i, s + 4);
2715 break;
2716 case 's':
2717 /* ssss -- 10-way fork */
2718 /* System registers mach, macl, pr: */
2719 for (j = 0; j < 3; j++)
2720 expand_opcode ((val << 4) | j, i, s + 4);
2721 /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2722 for (j = 5; j < 12; j++)
2723 expand_opcode ((val << 4) | j, i, s + 4);
2724 break;
2725 case 'X':
2726 /* XX/XY -- 2/4 way fork. */
2727 for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1))
2728 expand_opcode ((val << 2) | j, i, s + 2);
2729 break;
2730 case 'a':
2731 /* aa/ax -- 2/4 way fork. */
2732 for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1))
2733 expand_opcode ((val << 2) | j, i, s + 2);
2734 break;
2735 case 'Y':
2736 /* YY/YX -- 2/4 way fork. */
2737 for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1)
2738 expand_opcode ((val << 2) | j, i, s + 2);
2739 break;
2740 case 'A':
2741 /* AA/AY: 2/4 way fork. */
2742 for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1)
2743 expand_opcode ((val << 2) | j, i, s + 2);
2744 break;
2745 case 'v':
2746 /* vv(VV) -- 4(16) way fork. */
2747 /* Vector register fv0/4/8/12. */
2748 if (s[2] == 'V')
2749 {
2750 /* 2 vector registers. */
2751 for (j = 0; j < 15; j++)
2752 expand_opcode ((val << 4) | j, i, s + 4);
2753 }
2754 else
2755 {
2756 /* 1 vector register. */
2757 for (j = 0; j < 4; j += 1)
2758 expand_opcode ((val << 2) | j, i, s + 2);
2759 }
2760 break;
2761 }
2762 }
2763 }
2764
2765 /* Print the jump table used to index an opcode into a switch
2766 statement entry. */
2767
2768 static void
2769 dumptable (name, size, start)
2770 char *name;
2771 int size;
2772 int start;
2773 {
2774 int lump = 256;
2775 int online = 16;
2776
2777 int i = start;
2778
2779 printf ("unsigned short %s[%d]={\n", name, size);
2780 while (i < start + size)
2781 {
2782 int j = 0;
2783
2784 printf ("/* 0x%x */\n", i);
2785
2786 while (j < lump)
2787 {
2788 int k = 0;
2789 while (k < online)
2790 {
2791 printf ("%2d", table[i + j + k]);
2792 if (j + k < lump)
2793 printf (",");
2794
2795 k++;
2796 }
2797 j += k;
2798 printf ("\n");
2799 }
2800 i += j;
2801 }
2802 printf ("};\n");
2803 }
2804
2805
2806 static void
2807 filltable (p)
2808 op *p;
2809 {
2810 static int index = 1;
2811
2812 sorttab ();
2813 for (; p->name; p++)
2814 {
2815 p->index = index++;
2816 expand_opcode (0, p->index, p->code);
2817 }
2818 }
2819
2820 /* Table already contains all the switch case tags for 16-bit opcode double
2821 data transfer (ddt) insns, and the switch case tag for processing parallel
2822 processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the
2823 latter tag to represent all combinations of ppi with ddt. */
2824 static void
2825 expand_ppi_movxy ()
2826 {
2827 int i;
2828
2829 for (i = 0xf000; i < 0xf400; i++)
2830 if (table[i])
2831 table[i + 0x800] = table[0xf800];
2832 }
2833
2834 static void
2835 gensim_caselist (p)
2836 op *p;
2837 {
2838 for (; p->name; p++)
2839 {
2840 int j;
2841 int sextbit = -1;
2842 int needm = 0;
2843 int needn = 0;
2844
2845 char *s = p->code;
2846
2847 printf (" /* %s %s */\n", p->name, p->code);
2848 printf (" case %d: \n", p->index);
2849
2850 printf (" {\n");
2851 while (*s)
2852 {
2853 switch (*s)
2854 {
2855 default:
2856 fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2857 *s);
2858 exit (1);
2859 break;
2860 case '?':
2861 /* Wildcard expansion, nothing to do here. */
2862 s += 2;
2863 break;
2864 case 'v':
2865 printf (" int v1 = ((iword >> 10) & 3) * 4;\n");
2866 s += 2;
2867 break;
2868 case 'V':
2869 printf (" int v2 = ((iword >> 8) & 3) * 4;\n");
2870 s += 2;
2871 break;
2872 case '0':
2873 case '1':
2874 s += 2;
2875 break;
2876 case '.':
2877 s += 4;
2878 break;
2879 case 'n':
2880 case 'e':
2881 printf (" int n = (iword >> 8) & 0xf;\n");
2882 needn = 1;
2883 s += 4;
2884 break;
2885 case 'N':
2886 printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2887 s += 2;
2888 break;
2889 case 'x':
2890 if (s[1] == 'y') /* xy */
2891 {
2892 printf (" int n = (iword & 3) ? \n");
2893 printf (" ((iword >> 9) & 1) + 4 : \n");
2894 printf (" REG_xy ((iword >> 8) & 3);\n");
2895 }
2896 else
2897 printf (" int n = ((iword >> 9) & 1) + 4;\n");
2898 needn = 1;
2899 s += 2;
2900 break;
2901 case 'y':
2902 if (s[1] == 'x') /* yx */
2903 {
2904 printf (" int n = (iword & 0xc) ? \n");
2905 printf (" ((iword >> 8) & 1) + 6 : \n");
2906 printf (" REG_yx ((iword >> 8) & 3);\n");
2907 }
2908 else
2909 printf (" int n = ((iword >> 8) & 1) + 6;\n");
2910 needn = 1;
2911 s += 2;
2912 break;
2913 case 'm':
2914 needm = 1;
2915 case 's':
2916 case 'M':
2917 case 'G':
2918 printf (" int m = (iword >> 4) & 0xf;\n");
2919 s += 4;
2920 break;
2921 case 'X':
2922 if (s[1] == 'Y') /* XY */
2923 {
2924 printf (" int m = (iword & 3) ? \n");
2925 printf (" ((iword >> 7) & 1) + 8 : \n");
2926 printf (" DSP_xy ((iword >> 6) & 3);\n");
2927 }
2928 else
2929 printf (" int m = ((iword >> 7) & 1) + 8;\n");
2930 s += 2;
2931 break;
2932 case 'a':
2933 if (s[1] == 'x') /* ax */
2934 {
2935 printf (" int m = (iword & 3) ? \n");
2936 printf (" 7 - ((iword >> 6) & 2) : \n");
2937 printf (" DSP_ax ((iword >> 6) & 3);\n");
2938 }
2939 else
2940 printf (" int m = 7 - ((iword >> 6) & 2);\n");
2941 s += 2;
2942 break;
2943 case 'Y':
2944 if (s[1] == 'X') /* YX */
2945 {
2946 printf (" int m = (iword & 0xc) ? \n");
2947 printf (" ((iword >> 6) & 1) + 10 : \n");
2948 printf (" DSP_yx ((iword >> 6) & 3);\n");
2949 }
2950 else
2951 printf (" int m = ((iword >> 6) & 1) + 10;\n");
2952 s += 2;
2953 break;
2954 case 'A':
2955 if (s[1] == 'Y') /* AY */
2956 {
2957 printf (" int m = (iword & 0xc) ? \n");
2958 printf (" 7 - ((iword >> 5) & 2) : \n");
2959 printf (" DSP_ay ((iword >> 6) & 3);\n");
2960 }
2961 else
2962 printf (" int m = 7 - ((iword >> 5) & 2);\n");
2963 s += 2;
2964 break;
2965
2966 case 'i':
2967 printf (" int i = (iword & 0x");
2968
2969 switch (s[1])
2970 {
2971 default:
2972 fprintf (stderr,
2973 "gensim_caselist: Unknown char '%c' in %s\n",
2974 s[1], s);
2975 exit (1);
2976 break;
2977 case '4':
2978 printf ("f");
2979 break;
2980 case '8':
2981 printf ("ff");
2982 break;
2983 case '1':
2984 sextbit = 12;
2985 printf ("fff");
2986 break;
2987 }
2988 printf (")");
2989
2990 switch (s[3])
2991 {
2992 default:
2993 fprintf (stderr,
2994 "gensim_caselist: Unknown char '%c' in %s\n",
2995 s[3], s);
2996 exit (1);
2997 break;
2998 case '.': /* eg. "i12." */
2999 break;
3000 case '1':
3001 break;
3002 case '2':
3003 printf (" << 1");
3004 break;
3005 case '4':
3006 printf (" << 2");
3007 break;
3008 }
3009 printf (";\n");
3010 s += 4;
3011 }
3012 }
3013 if (sextbit > 0)
3014 {
3015 printf (" i = (i ^ (1 << %d)) - (1 << %d);\n",
3016 sextbit - 1, sextbit - 1);
3017 }
3018
3019 if (needm && needn)
3020 printf (" TB (m,n);\n");
3021 else if (needm)
3022 printf (" TL (m);\n");
3023 else if (needn)
3024 printf (" TL (n);\n");
3025
3026 {
3027 /* Do the refs. */
3028 char *r;
3029 for (r = p->refs; *r; r++)
3030 {
3031 if (*r == 'f') printf (" CREF (15);\n");
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-- > 0);\n");
3039 printf (" }\n");
3040 }
3041 if (*r == '+')
3042 {
3043 printf (" {\n");
3044 printf (" int i = n;\n");
3045 printf (" do {\n");
3046 printf (" CREF (i);\n");
3047 printf (" } while (i++ < 14);\n");
3048 printf (" }\n");
3049 }
3050 if (*r == '0') printf (" CREF (0);\n");
3051 if (*r == '8') printf (" CREF (8);\n");
3052 if (*r == '9') printf (" CREF (9);\n");
3053 if (*r == 'n') printf (" CREF (n);\n");
3054 if (*r == 'm') printf (" CREF (m);\n");
3055 }
3056 }
3057
3058 printf (" {\n");
3059 for (j = 0; j < MAX_NR_STUFF; j++)
3060 {
3061 if (p->stuff[j])
3062 {
3063 printf (" %s\n", p->stuff[j]);
3064 }
3065 }
3066 printf (" }\n");
3067
3068 {
3069 /* Do the defs. */
3070 char *r;
3071 for (r = p->defs; *r; r++)
3072 {
3073 if (*r == 'f') printf (" CDEF (15);\n");
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-- > 0);\n");
3081 printf (" }\n");
3082 }
3083 if (*r == '+')
3084 {
3085 printf (" {\n");
3086 printf (" int i = n;\n");
3087 printf (" do {\n");
3088 printf (" CDEF (i);\n");
3089 printf (" } while (i++ < 14);\n");
3090 printf (" }\n");
3091 }
3092 if (*r == '0') printf (" CDEF (0);\n");
3093 if (*r == 'n') printf (" CDEF (n);\n");
3094 if (*r == 'm') printf (" CDEF (m);\n");
3095 }
3096 }
3097
3098 printf (" break;\n");
3099 printf (" }\n");
3100 }
3101 }
3102
3103 static void
3104 gensim ()
3105 {
3106 printf ("{\n");
3107 printf ("/* REG_xy = [r4, r5, r0, r1]. */\n");
3108 printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ? 0 : 1)\n");
3109 printf ("/* REG_yx = [r6, r7, r2, r3]. */\n");
3110 printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ? 2 : 3)\n");
3111 printf ("/* DSP_ax = [a0, a1, x0, x1]. */\n");
3112 printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ? 8 : 9)\n");
3113 printf ("/* DSP_ay = [a0, a1, y0, y1]. */\n");
3114 printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3115 printf ("/* DSP_xy = [x0, x1, y0, y1]. */\n");
3116 printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3117 printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
3118 printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3119 printf (" switch (jump_table[iword]) {\n");
3120
3121 gensim_caselist (tab);
3122 gensim_caselist (movsxy_tab);
3123
3124 printf (" default:\n");
3125 printf (" {\n");
3126 printf (" RAISE_EXCEPTION (SIGILL);\n");
3127 printf (" }\n");
3128 printf (" }\n");
3129 printf ("}\n");
3130 }
3131
3132 static void
3133 gendefines ()
3134 {
3135 op *p;
3136 filltable (tab);
3137 for (p = tab; p->name; p++)
3138 {
3139 char *s = p->name;
3140 printf ("#define OPC_");
3141 while (*s) {
3142 if (isupper (*s))
3143 *s = tolower (*s);
3144 if (isalpha (*s))
3145 printf ("%c", *s);
3146 if (*s == ' ')
3147 printf ("_");
3148 if (*s == '@')
3149 printf ("ind_");
3150 if (*s == ',')
3151 printf ("_");
3152 s++;
3153 }
3154 printf (" %d\n",p->index);
3155 }
3156 }
3157
3158 static int ppi_index;
3159
3160 /* Take a ppi code, expand all varying fields in it and fill all the
3161 right entries in 'table' with the opcode index.
3162 NOTE: tail recursion optimization removed for simplicity. */
3163
3164 static void
3165 expand_ppi_code (val, i, s)
3166 int val;
3167 int i;
3168 char *s;
3169 {
3170 int j;
3171
3172 switch (s[0])
3173 {
3174 default:
3175 fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]);
3176 exit (2);
3177 break;
3178 case 'g':
3179 case 'z':
3180 if (warn_conflicts && table[val] != 0)
3181 conflict_warn (val, i);
3182
3183 /* The last four bits are disregarded for the switch table. */
3184 table[val] = i;
3185 return;
3186 case 'm':
3187 /* Four-bit expansion. */
3188 for (j = 0; j < 16; j++)
3189 expand_ppi_code ((val << 4) + j, i, s + 4);
3190 break;
3191 case '.':
3192 case '0':
3193 expand_ppi_code ((val << 1), i, s + 1);
3194 break;
3195 case '1':
3196 expand_ppi_code ((val << 1) + 1, i, s + 1);
3197 break;
3198 case 'i':
3199 case 'e': case 'f':
3200 case 'x': case 'y':
3201 expand_ppi_code ((val << 1), i, s + 1);
3202 expand_ppi_code ((val << 1) + 1, i, s + 1);
3203 break;
3204 case 'c':
3205 expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2);
3206 expand_ppi_code ((val << 2) + 2, i, s + 2);
3207 expand_ppi_code ((val << 2) + 3, i, s + 2);
3208 break;
3209 }
3210 }
3211
3212 static void
3213 ppi_filltable ()
3214 {
3215 op *p;
3216 ppi_index = 1;
3217
3218 for (p = ppi_tab; p->name; p++)
3219 {
3220 p->index = ppi_index++;
3221 expand_ppi_code (0, p->index, p->code);
3222 }
3223 }
3224
3225 static void
3226 ppi_gensim ()
3227 {
3228 op *p = ppi_tab;
3229
3230 printf ("#define DSR_MASK_G 0x80\n");
3231 printf ("#define DSR_MASK_Z 0x40\n");
3232 printf ("#define DSR_MASK_N 0x20\n");
3233 printf ("#define DSR_MASK_V 0x10\n");
3234 printf ("\n");
3235 printf ("#define COMPUTE_OVERFLOW do {\\\n");
3236 printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3237 printf (" if (overflow && S) \\\n");
3238 printf (" { \\\n");
3239 printf (" if (res_grd & 0x80) \\\n");
3240 printf (" { \\\n");
3241 printf (" res = 0x80000000; \\\n");
3242 printf (" res_grd |= 0xff; \\\n");
3243 printf (" } \\\n");
3244 printf (" else \\\n");
3245 printf (" { \\\n");
3246 printf (" res = 0x7fffffff; \\\n");
3247 printf (" res_grd &= ~0xff; \\\n");
3248 printf (" } \\\n");
3249 printf (" overflow = 0; \\\n");
3250 printf (" } \\\n");
3251 printf ("} while (0)\n");
3252 printf ("\n");
3253 printf ("#define ADD_SUB_GE \\\n");
3254 printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3255 printf ("\n");
3256 printf ("static void\n");
3257 printf ("ppi_insn (iword)\n");
3258 printf (" int iword;\n");
3259 printf ("{\n");
3260 printf (" /* 'ee' = [x0, x1, y0, a1] */\n");
3261 printf (" static char e_tab[] = { 8, 9, 10, 5};\n");
3262 printf (" /* 'ff' = [y0, y1, x0, a1] */\n");
3263 printf (" static char f_tab[] = {10, 11, 8, 5};\n");
3264 printf (" /* 'xx' = [x0, x1, a0, a1] */\n");
3265 printf (" static char x_tab[] = { 8, 9, 7, 5};\n");
3266 printf (" /* 'yy' = [y0, y1, m0, m1] */\n");
3267 printf (" static char y_tab[] = {10, 11, 12, 14};\n");
3268 printf (" /* 'gg' = [m0, m1, a0, a1] */\n");
3269 printf (" static char g_tab[] = {12, 14, 7, 5};\n");
3270 printf (" /* 'uu' = [x0, y0, a0, a1] */\n");
3271 printf (" static char u_tab[] = { 8, 10, 7, 5};\n");
3272 printf ("\n");
3273 printf (" int z;\n");
3274 printf (" int res, res_grd;\n");
3275 printf (" int carry, overflow, greater_equal;\n");
3276 printf ("\n");
3277 printf (" switch (ppi_table[iword >> 4]) {\n");
3278
3279 for (; p->name; p++)
3280 {
3281 int shift, j;
3282 int cond = 0;
3283 int havedecl = 0;
3284
3285 char *s = p->code;
3286
3287 printf (" /* %s %s */\n", p->name, p->code);
3288 printf (" case %d: \n", p->index);
3289
3290 printf (" {\n");
3291 for (shift = 16; *s; )
3292 {
3293 switch (*s)
3294 {
3295 case 'i':
3296 printf (" int i = (iword >> 4) & 0x7f;\n");
3297 s += 6;
3298 break;
3299 case 'e':
3300 case 'f':
3301 case 'x':
3302 case 'y':
3303 case 'g':
3304 case 'u':
3305 shift -= 2;
3306 printf (" int %c = %c_tab[(iword >> %d) & 3];\n",
3307 *s, *s, shift);
3308 havedecl = 1;
3309 s += 2;
3310 break;
3311 case 'c':
3312 printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3313 printf ("\treturn;\n");
3314 printf (" }\n");
3315 printf (" case %d: \n", p->index + 1);
3316 printf (" {\n");
3317 cond = 1;
3318 case '0':
3319 case '1':
3320 case '.':
3321 shift -= 2;
3322 s += 2;
3323 break;
3324 case 'z':
3325 if (havedecl)
3326 printf ("\n");
3327 printf (" z = iword & 0xf;\n");
3328 havedecl = 2;
3329 s += 4;
3330 break;
3331 }
3332 }
3333 if (havedecl == 1)
3334 printf ("\n");
3335 else if (havedecl == 2)
3336 printf (" {\n");
3337 for (j = 0; j < MAX_NR_STUFF; j++)
3338 {
3339 if (p->stuff[j])
3340 {
3341 printf (" %s%s\n",
3342 (havedecl == 2 ? " " : ""),
3343 p->stuff[j]);
3344 }
3345 }
3346 if (havedecl == 2)
3347 printf (" }\n");
3348 if (cond)
3349 {
3350 printf (" if (iword & 0x200)\n");
3351 printf (" goto assign_z;\n");
3352 }
3353 printf (" break;\n");
3354 printf (" }\n");
3355 }
3356
3357 printf (" default:\n");
3358 printf (" {\n");
3359 printf (" RAISE_EXCEPTION (SIGILL);\n");
3360 printf (" return;\n");
3361 printf (" }\n");
3362 printf (" }\n");
3363 printf (" DSR &= ~0xf1;\n");
3364 printf (" if (res || res_grd)\n");
3365 printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3366 printf (" else\n");
3367 printf (" DSR |= DSR_MASK_Z | overflow;\n");
3368 printf (" assign_dc:\n");
3369 printf (" switch (DSR >> 1 & 7)\n");
3370 printf (" {\n");
3371 printf (" case 0: /* Carry Mode */\n");
3372 printf (" DSR |= carry;\n");
3373 printf (" case 1: /* Negative Value Mode */\n");
3374 printf (" DSR |= res_grd >> 7 & 1;\n");
3375 printf (" case 2: /* Zero Value Mode */\n");
3376 printf (" DSR |= DSR >> 6 & 1;\n");
3377 printf (" case 3: /* Overflow mode\n");
3378 printf (" DSR |= overflow >> 4;\n");
3379 printf (" case 4: /* Signed Greater Than Mode */\n");
3380 printf (" DSR |= DSR >> 7 & 1;\n");
3381 printf (" case 4: /* Signed Greater Than Or Equal Mode */\n");
3382 printf (" DSR |= greater_equal >> 7;\n");
3383 printf (" }\n");
3384 printf (" assign_z:\n");
3385 printf (" if (0xa05f >> z & 1)\n");
3386 printf (" {\n");
3387 printf (" RAISE_EXCEPTION (SIGILL);\n");
3388 printf (" return;\n");
3389 printf (" }\n");
3390 printf (" DSP_R (z) = res;\n");
3391 printf (" DSP_GRD (z) = res_grd;\n");
3392 printf ("}\n");
3393 }
3394
3395 int
3396 main (ac, av)
3397 int ac;
3398 char **av;
3399 {
3400 /* Verify the table before anything else. */
3401 {
3402 op *p;
3403 for (p = tab; p->name; p++)
3404 {
3405 /* Check that the code field contains 16 bits. */
3406 if (strlen (p->code) != 16)
3407 {
3408 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
3409 p->code, strlen (p->code), p->name);
3410 abort ();
3411 }
3412 }
3413 }
3414
3415 /* Now generate the requested data. */
3416 if (ac > 1)
3417 {
3418 if (ac > 2 && strcmp (av[2], "-w") == 0)
3419 {
3420 warn_conflicts = 1;
3421 }
3422 if (strcmp (av[1], "-t") == 0)
3423 {
3424 gengastab ();
3425 }
3426 else if (strcmp (av[1], "-d") == 0)
3427 {
3428 gendefines ();
3429 }
3430 else if (strcmp (av[1], "-s") == 0)
3431 {
3432 filltable (tab);
3433 dumptable ("sh_jump_table", 1 << 16, 0);
3434
3435 memset (table, 0, sizeof table);
3436 filltable (movsxy_tab);
3437 expand_ppi_movxy ();
3438 dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3439
3440 memset (table, 0, sizeof table);
3441 ppi_filltable ();
3442 dumptable ("ppi_table", 1 << 12, 0);
3443 }
3444 else if (strcmp (av[1], "-x") == 0)
3445 {
3446 filltable (tab);
3447 filltable (movsxy_tab);
3448 gensim ();
3449 }
3450 else if (strcmp (av[1], "-p") == 0)
3451 {
3452 ppi_filltable ();
3453 ppi_gensim ();
3454 }
3455 }
3456 else
3457 fprintf (stderr, "Opcode table generation no longer supported.\n");
3458 return 0;
3459 }