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