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