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