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