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