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