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