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