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