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