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