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