]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh/gencode.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / sh / gencode.c
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
28 default generates the opcode tables
29
30 */
31
32 #include <stdio.h>
33
34 #define MAX_NR_STUFF 20
35
36 typedef struct
37 {
38 char *defs;
39 char *refs;
40 char *name;
41 char *code;
42 char *stuff[MAX_NR_STUFF];
43 int index;
44 }
45
46 op;
47
48
49 op tab[] =
50 {
51
52 { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
53 "R[n] += SEXT(i);",
54 "if (i == 0) {",
55 " UNDEF(n); /* see #ifdef PARANOID */",
56 " break;",
57 "}",
58 },
59 { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
60 "R[n] += R[m];",
61 },
62
63 { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
64 "ult = R[n] + T;",
65 "SET_SR_T (ult < R[n]);",
66 "R[n] = ult + R[m];",
67 "SET_SR_T (T || (R[n] < ult));",
68 },
69
70 { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
71 "ult = R[n] + R[m];",
72 "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
73 "R[n] = ult;",
74 },
75
76 { "0", "", "and #<imm>,R0", "11001001i8*1....",
77 "R0 &= i;",
78 },
79 { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
80 "R[n] &= R[m];",
81 },
82 { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
83 "MA (1);",
84 "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
85 },
86
87 { "", "", "bf <bdisp8>", "10001011i8p1....",
88 "if (!T) {",
89 " nia = PC + 4 + (SEXT(i) * 2);",
90 " cycles += 2;",
91 "}",
92 },
93
94 { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95 "if (!T) {",
96 " nia = PC + 4 + (SEXT (i) * 2);",
97 " cycles += 2;",
98 " Delay_Slot (PC + 2);",
99 "}",
100 },
101
102 { "", "", "bra <bdisp12>", "1010i12.........",
103 "nia = PC + 4 + (SEXT12 (i) * 2);",
104 "Delay_Slot (PC + 2);",
105 },
106
107 { "", "n", "braf <REG_N>", "0000nnnn00100011",
108 "nia = PC + 4 + R[n];",
109 "Delay_Slot (PC + 2);",
110 },
111
112 { "", "", "bsr <bdisp12>", "1011i12.........",
113 "PR = PC + 4;",
114 "nia = PC + 4 + (SEXT12 (i) * 2);",
115 "Delay_Slot (PC + 2);",
116 },
117
118 { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
119 "PR = PC + 4;",
120 "nia = PC + 4 + R[n];",
121 "Delay_Slot (PC + 2);",
122 },
123
124 { "", "", "bt <bdisp8>", "10001001i8p1....",
125 "if (T) {",
126 " nia = PC + 4 + (SEXT (i) * 2);",
127 " cycles += 2;",
128 "}",
129 },
130
131 { "", "", "bt.s <bdisp8>", "10001101i8p1....",
132 "if (T) {",
133 " nia = PC + 4 + (SEXT (i) * 2);",
134 " cycles += 2;",
135 " Delay_Slot (PC + 2);",
136 "}",
137 },
138
139 { "", "", "clrmac", "0000000000101000",
140 "MACH = 0;",
141 "MACL = 0;",
142 },
143
144 { "", "", "clrs", "0000000001001000",
145 "SET_SR_S (0);",
146 },
147
148 { "", "", "clrt", "0000000000001000",
149 "SET_SR_T (0);",
150 },
151
152 { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
153 "SET_SR_T (R0 == SEXT (i));",
154 },
155 { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
156 "SET_SR_T (R[n] == R[m]);",
157 },
158 { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
159 "SET_SR_T (R[n] >= R[m]);",
160 },
161 { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
162 "SET_SR_T (R[n] > R[m]);",
163 },
164 { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
165 "SET_SR_T (UR[n] > UR[m]);",
166 },
167 { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
168 "SET_SR_T (UR[n] >= UR[m]);",
169 },
170 { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
171 "SET_SR_T (R[n] > 0);",
172 },
173 { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
174 "SET_SR_T (R[n] >= 0);",
175 },
176 { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
177 "ult = R[n] ^ R[m];",
178 "SET_SR_T (((ult & 0xff000000) == 0)",
179 " | ((ult & 0xff0000) == 0)",
180 " | ((ult & 0xff00) == 0)",
181 " | ((ult & 0xff) == 0));",
182 },
183
184 { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
185 "SET_SR_Q ((R[n] & sbit) != 0);",
186 "SET_SR_M ((R[m] & sbit) != 0);",
187 "SET_SR_T (M != Q);",
188 },
189
190 { "", "", "div0u", "0000000000011001",
191 "SET_SR_M (0);",
192 "SET_SR_Q (0);",
193 "SET_SR_T (0);",
194 },
195
196 { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
197 "div1 (R, m, n/*, T*/);",
198 },
199
200 { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
201 "dmul (1/*signed*/, R[n], R[m]);",
202 },
203
204 { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
205 "dmul (0/*unsigned*/, R[n], R[m]);",
206 },
207
208 { "n", "n", "dt <REG_N>", "0100nnnn00010000",
209 "R[n]--;",
210 "SET_SR_T (R[n] == 0);",
211 },
212
213 { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
214 "R[n] = SEXT (R[m]);",
215 },
216 { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
217 "R[n] = SEXTW (R[m]);",
218 },
219
220 { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
221 "R[n] = (R[m] & 0xff);",
222 },
223 { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
224 "R[n] = (R[m] & 0xffff);",
225 },
226
227 /* sh3e */
228 { "", "", "fabs <FREG_N>", "1111nnnn01011101",
229 "FP_UNARY (n, fabs);",
230 "/* FIXME: FR(n) &= 0x7fffffff; */",
231 },
232
233 /* sh3e */
234 { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
235 "FP_OP (n, +, m);",
236 },
237
238 /* sh3e */
239 { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
240 "FP_CMP (n, ==, m);",
241 },
242 /* sh3e */
243 { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
244 "FP_CMP (n, >, m);",
245 },
246
247 /* sh3e */
248 { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
249 "FP_OP (n, /, m);",
250 "/* FIXME: check for DP and (n & 1) == 0? */",
251 },
252
253 /* sh3e */
254 { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
255 "SET_FR (n, (float)0.0);",
256 "/* FIXME: check for DP and (n & 1) == 0? */",
257 },
258
259 /* sh3e */
260 { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
261 "SET_FR (n, (float)1.0);",
262 "/* FIXME: check for DP and (n & 1) == 0? */",
263 },
264
265 /* sh3e */
266 { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
267 "char buf[4];",
268 "*(float *)buf = FR(n);",
269 "FPUL = *(int *)buf;",
270 },
271
272 /* sh3e */
273 { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
274 "{",
275 " SET_FR (n, (float)FPUL);",
276 "}",
277 },
278
279 /* sh3e */
280 { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
281 "SET_FR (n, FR(m) * FR(0) + FR(n));",
282 "/* FIXME: check for DP and (n & 1) == 0? */",
283 },
284
285 /* sh3e */
286 { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
287 "{",
288 " SET_FR (n, FR (m));",
289 "}",
290 },
291 /* sh3e */
292 { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
293 "{",
294 " MA (1);",
295 " WLAT (R[n], FI(m));",
296 "}",
297 },
298 /* sh3e */
299 { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
300 "{",
301 " MA (1);",
302 " SET_FI(n, RLAT(R[m]));",
303 "}",
304 },
305 /* sh3e */
306 { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
307 "{",
308 " MA (1);",
309 " SET_FI (n, RLAT (R[m]));",
310 " R[m] += 4;",
311 "}",
312 },
313 /* sh3e */
314 { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
315 "{",
316 " MA (1);",
317 " R[n] -= 4;",
318 " WLAT (R[n], FI(m));",
319 "}",
320 },
321 /* sh3e */
322 { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
323 "{",
324 " MA (1);",
325 " SET_FI(n, RLAT(R[0] + R[m]));",
326 "}",
327 },
328 /* sh3e */
329 { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
330 "{",
331 " MA (1);",
332 " WLAT((R[0]+R[n]), FI(m));",
333 "}",
334 },
335
336 /* sh3e */
337 { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
338 "FP_OP(n, *, m);",
339 },
340
341 /* sh3e */
342 { "", "", "fneg <FREG_N>", "1111nnnn01001101",
343 "FP_UNARY(n, -);",
344 },
345
346 /* sh3e */
347 { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
348 "FP_UNARY(n, sqrt);",
349 },
350
351 /* sh3e */
352 { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
353 "FP_OP(n, -, m);",
354 },
355
356 /* sh3e */
357 { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
358 "if (FR(n) != FR(n)) /* NaN */",
359 " FPUL = 0x80000000;",
360 "else",
361 " FPUL = (int)FR(n);",
362 },
363
364 /* sh3e */
365 { "", "", "ftst/nan <FREG_N>", "1111nnnn01111101",
366 "SET_SR_T (isnan (FR(n)));",
367 },
368 /* sh3e */
369 { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
370 "char buf[4];",
371 "*(int *)buf = FPUL;",
372 "SET_FR (n, *(float *)buf);",
373 },
374
375 { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
376 "nia = R[n];",
377 "Delay_Slot (PC + 2);",
378 },
379
380 { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
381 "PR = PC + 4;",
382 "nia = R[n];",
383 "if (~doprofile)",
384 " gotcall (PR, nia);",
385 "Delay_Slot (PC + 2);",
386 },
387
388 { "", "n", "ldc <REG_N>,GBR", "0100nnnn00011110",
389 "GBR = R[n];",
390 "/* FIXME: user mode */",
391 },
392 { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
393 "SET_SR (R[n]);",
394 "/* FIXME: user mode */",
395 },
396 { "", "n", "ldc <REG_N>,VBR", "0100nnnn00101110",
397 "VBR = R[n];",
398 "/* FIXME: user mode */",
399 },
400 { "", "n", "ldc <REG_N>,SSR", "0100nnnn00111110",
401 "SSR = R[n];",
402 "/* FIXME: user mode */",
403 },
404 { "", "n", "ldc <REG_N>,SPC", "0100nnnn01001110",
405 "SPC = R[n];",
406 "/* FIXME: user mode */",
407 },
408 { "", "n", "ldc <REG_N>,R0_BANK", "0100nnnn10001110",
409 "SET_Rn_BANK (0, R[n]);",
410 "/* FIXME: user mode */",
411 },
412 { "", "n", "ldc <REG_N>,R1_BANK", "0100nnnn10011110",
413 "SET_Rn_BANK (1, R[n]);",
414 "/* FIXME: user mode */",
415 },
416 { "", "n", "ldc <REG_N>,R2_BANK", "0100nnnn10101110",
417 "SET_Rn_BANK (2, R[n]);",
418 "/* FIXME: user mode */",
419 },
420 { "", "n", "ldc <REG_N>,R3_BANK", "0100nnnn10111110",
421 "SET_Rn_BANK (3, R[n]);",
422 "/* FIXME: user mode */",
423 },
424 { "", "n", "ldc <REG_N>,R4_BANK", "0100nnnn11001110",
425 "SET_Rn_BANK (4, R[n]);",
426 "/* FIXME: user mode */",
427 },
428 { "", "n", "ldc <REG_N>,R5_BANK", "0100nnnn11011110",
429 "SET_Rn_BANK (5, R[n]);",
430 "/* FIXME: user mode */",
431 },
432 { "", "n", "ldc <REG_N>,R6_BANK", "0100nnnn11101110",
433 "SET_Rn_BANK (6, R[n]);",
434 "/* FIXME: user mode */",
435 },
436 { "", "n", "ldc <REG_N>,R7_BANK", "0100nnnn11111110",
437 "SET_Rn_BANK (7, R[n]);",
438 "/* FIXME: user mode */",
439 },
440 { "", "n", "ldc.l @<REG_N>+,GBR", "0100nnnn00010111",
441 "MA (1);",
442 "GBR = RLAT (R[n]);",
443 "R[n] += 4;",
444 "/* FIXME: user mode */",
445 },
446 { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
447 "MA (1);",
448 "SET_SR (RLAT (R[n]));",
449 "R[n] += 4;",
450 "/* FIXME: user mode */",
451 },
452 { "", "n", "ldc.l @<REG_N>+,VBR", "0100nnnn00100111",
453 "MA (1);",
454 "VBR = RLAT (R[n]);",
455 "R[n] += 4;",
456 "/* FIXME: user mode */",
457 },
458 { "", "n", "ldc.l @<REG_N>+,SSR", "0100nnnn00110111",
459 "MA (1);",
460 "SSR = RLAT (R[n]);",
461 "R[n] += 4;",
462 "/* FIXME: user mode */",
463 },
464 { "", "n", "ldc.l @<REG_N>+,SPC", "0100nnnn01000111",
465 "MA (1);",
466 "SPC = RLAT (R[n]);",
467 "R[n] += 4;",
468 "/* FIXME: user mode */",
469 },
470 { "", "n", "ldc.l @<REG_N>+,R0_BANK", "0100nnnn10000111",
471 "MA (1);",
472 "SET_Rn_BANK (0, RLAT (R[n]));",
473 "R[n] += 4;",
474 "/* FIXME: user mode */",
475 },
476 { "", "n", "ldc.l @<REG_N>+,R1_BANK", "0100nnnn10010111",
477 "MA (1);",
478 "SET_Rn_BANK (1, RLAT (R[n]));",
479 "R[n] += 4;",
480 "/* FIXME: user mode */",
481 },
482 { "", "n", "ldc.l @<REG_N>+,R2_BANK", "0100nnnn10100111",
483 "MA (1);",
484 "SET_Rn_BANK (2, RLAT (R[n]));",
485 "R[n] += 4;",
486 "/* FIXME: user mode */",
487 },
488 { "", "n", "ldc.l @<REG_N>+,R3_BANK", "0100nnnn10110111",
489 "MA (1);",
490 "SET_Rn_BANK (3, RLAT (R[n]));",
491 "R[n] += 4;",
492 "/* FIXME: user mode */",
493 },
494 { "", "n", "ldc.l @<REG_N>+,R4_BANK", "0100nnnn11000111",
495 "MA (1);",
496 "SET_Rn_BANK (4, RLAT (R[n]));",
497 "R[n] += 4;",
498 "/* FIXME: user mode */",
499 },
500 { "", "n", "ldc.l @<REG_N>+,R5_BANK", "0100nnnn11010111",
501 "MA (1);",
502 "SET_Rn_BANK (5, RLAT (R[n]));",
503 "R[n] += 4;",
504 "/* FIXME: user mode */",
505 },
506 { "", "n", "ldc.l @<REG_N>+,R6_BANK", "0100nnnn11100111",
507 "MA (1);",
508 "SET_Rn_BANK (6, RLAT (R[n]));",
509 "R[n] += 4;",
510 "/* FIXME: user mode */",
511 },
512 { "", "n", "ldc.l @<REG_N>+,R7_BANK", "0100nnnn11110111",
513 "MA (1);",
514 "SET_Rn_BANK (7, RLAT (R[n]));",
515 "R[n] += 4;",
516 "/* FIXME: user mode */",
517 },
518
519 /* sh3e */
520 { "", "", "lds <REG_N>,FPUL", "0100nnnn01011010",
521 "FPUL = R[n];",
522 },
523 /* sh3e */
524 { "", "", "lds.l @<REG_N>+,FPUL", "0100nnnn01010110",
525 "MA (1);",
526 "FPUL = RLAT(R[n]);",
527 "R[n] += 4;",
528 },
529 /* sh3e */
530 { "", "", "lds <REG_N>,FPSCR", "0100nnnn01101010",
531 "SET_FPSCR(R[n]);",
532 },
533 /* sh3e */
534 { "", "", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
535 "MA (1);",
536 "SET_FPSCR (RLAT(R[n]));",
537 "R[n] += 4;",
538 },
539
540 { "", "n", "lds <REG_N>,MACH", "0100nnnn00001010",
541 "MACH = R[n];",
542 },
543 { "", "n", "lds <REG_N>,MACL", "0100nnnn00011010",
544 "MACL= R[n];",
545 },
546 { "", "n", "lds <REG_N>,PR", "0100nnnn00101010",
547 "PR = R[n];",
548 },
549 { "", "n", "lds.l @<REG_N>+,MACH", "0100nnnn00000110",
550 "MA (1);",
551 "MACH = SEXT(RLAT(R[n]));",
552 "R[n]+=4;",
553 },
554 { "", "n", "lds.l @<REG_N>+,MACL", "0100nnnn00010110",
555 "MA (1);",
556 "MACL = RLAT(R[n]);",
557 "R[n]+=4;",
558 },
559 { "", "n", "lds.l @<REG_N>+,PR", "0100nnnn00100110",
560 "MA (1);",
561 "PR = RLAT(R[n]);",
562 "R[n]+=4;;",
563 },
564
565 { "", "", "ldtlb", "0000000000111000",
566 "/* FIXME: XXX*/ abort();",
567 },
568
569 { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
570 "trap (255,R0,memory,maskl,maskw,little_endian);",
571 "/* FIXME: mac.l support */",
572 },
573
574 { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
575 "macw(R0,memory,n,m);",
576 },
577
578 { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
579 "R[n] = SEXT(i);",
580 },
581 { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
582 "R[n] = R[m];",
583 },
584
585 { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
586 "MA (1);",
587 "R0 = RSBAT (i + GBR);",
588 "L (0);",
589 },
590 { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
591 "MA (1);",
592 "R0 = RSBAT (i + R[m]);",
593 "L (0);",
594 },
595 { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
596 "MA (1);",
597 "R[n] = RSBAT (R0 + R[m]);",
598 "L (n);",
599 },
600 { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
601 "MA (1);",
602 "R[n] = RSBAT (R[m]);",
603 "R[m] += 1;",
604 "L (n);",
605 },
606 { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
607 "MA (1);",
608 "WBAT (R[n], R[m]);",
609 },
610 { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
611 "MA (1);",
612 "WBAT (i + GBR, R0);",
613 },
614 { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
615 "MA (1);",
616 "WBAT (i + R[m], R0);",
617 },
618 { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
619 "MA (1);",
620 "WBAT (R[n] + R0, R[m]);",
621 },
622 { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
623 "MA (1);",
624 "R[n] -= 1;",
625 "WBAT (R[n], R[m]);",
626 },
627 { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
628 "MA (1);",
629 "R[n] = RSBAT (R[m]);",
630 "L (n);",
631 },
632
633 { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
634 "MA (1);",
635 "R0 = RLAT (i + GBR);",
636 "L (0);",
637 },
638 { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
639 "MA (1);",
640 "R[n] = RLAT((PC & ~3) + 4 + i);",
641 "L (n);",
642 },
643 { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
644 "MA (1);",
645 "R[n] = RLAT (i + R[m]);",
646 "L (n);",
647 },
648 { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
649 "MA (1);",
650 "R[n] = RLAT (R0 + R[m]);",
651 "L (n);",
652 },
653 { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
654 "MA (1);",
655 "R[n] = RLAT (R[m]);",
656 "R[m] += 4;",
657 "L (n);",
658 },
659 { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
660 "MA (1);",
661 "R[n] = RLAT (R[m]);",
662 "L (n);",
663 },
664 { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
665 "MA (1);",
666 "WLAT (i + GBR, R0);",
667 },
668 { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
669 "MA (1);",
670 "WLAT (i + R[n], R[m]);",
671 },
672 { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
673 "MA (1);",
674 "WLAT (R0 + R[n], R[m]);",
675 },
676 { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
677 "MA (1) ;",
678 "R[n] -= 4;",
679 "WLAT (R[n], R[m]);",
680 },
681 { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
682 "MA (1);",
683 "WLAT (R[n], R[m]);",
684 },
685
686 { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
687 "MA (1)",
688 ";R0 = RSWAT (i + GBR);",
689 "L (0);",
690 },
691 { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
692 "MA (1);",
693 "R[n] = RSWAT (PC + 4 + i);",
694 "L (n);",
695 },
696 { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
697 "MA (1);",
698 "R0 = RSWAT (i + R[m]);",
699 "L (0);",
700 },
701 { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
702 "MA (1);",
703 "R[n] = RSWAT (R0 + R[m]);",
704 "L (n);",
705 },
706 { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
707 "MA (1);",
708 "R[n] = RSWAT (R[m]);",
709 "R[m] += 2;",
710 "L (n);",
711 },
712 { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
713 "MA (1);",
714 "R[n] = RSWAT (R[m]);",
715 "L (n);",
716 },
717 { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
718 "MA (1);",
719 "WWAT (i + GBR, R0);",
720 },
721 { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
722 "MA (1);",
723 "WWAT (i + R[m], R0);",
724 },
725 { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
726 "MA (1);",
727 "WWAT (R0 + R[n], R[m]);",
728 },
729 { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
730 "MA (1);",
731 "R[n] -= 2;",
732 "WWAT (R[n], R[m]);",
733 },
734 { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
735 "MA (1);",
736 "WWAT (R[n], R[m]);",
737 },
738
739 { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
740 "R0 = ((i + 4 + PC) & ~0x3);",
741 },
742
743 { "n", "", "movt <REG_N>", "0000nnnn00101001",
744 "R[n] = T;",
745 },
746
747 { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
748 "MACL = ((int)R[n]) * ((int)R[m]);",
749 },
750 #if 0
751 { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
752 "MACL = R[n] * R[m];",
753 },
754 #endif
755
756 /* muls.w - see muls */
757 { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
758 "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
759 },
760
761 /* mulu.w - see mulu */
762 { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
763 "MACL = (((unsigned int)(unsigned short)R[n])",
764 " * ((unsigned int)(unsigned short)R[m]));",
765 },
766
767 { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
768 "R[n] = - R[m];",
769 },
770
771 { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
772 "ult = -T;",
773 "SET_SR_T (ult > 0);",
774 "R[n] = ult - R[m];",
775 "SET_SR_T (T || (R[n] > ult));",
776 },
777
778 { "", "", "nop", "0000000000001001",
779 "/* nop */",
780 },
781
782 { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
783 "R[n] = ~R[m];",
784 },
785
786 { "0", "", "or #<imm>,R0", "11001011i8*1....",
787 "R0 |= i;",
788 },
789 { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
790 "R[n] |= R[m];",
791 },
792 { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
793 "MA (1);",
794 "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
795 },
796
797 { "", "n", "pref @<REG_N>", "0000nnnn10000011",
798 "/* Except for the effect on the cache - which is not simulated -",
799 " this is like a nop. */",
800 },
801
802 { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
803 "ult = R[n] < 0;",
804 "R[n] = (R[n] << 1) | T;",
805 "SET_SR_T (ult);",
806 },
807
808 { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
809 "ult = R[n] & 1;",
810 "R[n] = (UR[n] >> 1) | (T << 31);",
811 "SET_SR_T (ult);",
812 },
813
814 { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
815 "SET_SR_T (R[n] < 0);",
816 "R[n] <<= 1;",
817 "R[n] |= T;",
818 },
819
820 { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
821 "SET_SR_T (R[n] & 1);",
822 "R[n] = UR[n] >> 1;",
823 "R[n] |= (T << 31);",
824 },
825
826 { "", "", "rte", "0000000000101011",
827 #if 0
828 /* SH-[12] */
829 "int tmp = PC;",
830 "nia = RLAT (R[15]) + 2;",
831 "R[15] += 4;",
832 "SET_SR (RLAT (R[15]) & 0x3f3);",
833 "R[15] += 4;",
834 "Delay_Slot (PC + 2);",
835 #else
836 "nia = SPC;",
837 "SET_SR (SSR);",
838 "Delay_Slot (PC + 2);",
839 #endif
840 },
841
842 { "", "", "rts", "0000000000001011",
843 "nia = PR;",
844 "Delay_Slot (PC + 2);",
845 },
846
847 { "", "", "sets", "0000000001011000",
848 "SET_SR_S (1);",
849 },
850
851 { "", "", "sett", "0000000000011000",
852 "SET_SR_T (1);",
853 },
854
855 { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
856 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
857 },
858
859 { "n", "n", "shal <REG_N>", "0100nnnn00100000",
860 "SET_SR_T (R[n] < 0);",
861 "R[n] <<= 1;",
862 },
863
864 { "n", "n", "shar <REG_N>", "0100nnnn00100001",
865 "SET_SR_T (R[n] & 1);",
866 "R[n] = R[n] >> 1;",
867 },
868
869 { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
870 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
871 },
872
873 { "n", "n", "shll <REG_N>", "0100nnnn00000000",
874 "SET_SR_T (R[n] < 0);",
875 "R[n] <<= 1;",
876 },
877
878 { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
879 "R[n] <<= 2;",
880 },
881 { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
882 "R[n] <<= 8;",
883 },
884 { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
885 "R[n] <<= 16;",
886 },
887
888 { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
889 "SET_SR_T (R[n] & 1);",
890 "R[n] = UR[n] >> 1;",
891 },
892
893 { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
894 "R[n] = UR[n] >> 2;",
895 },
896 { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
897 "R[n] = UR[n] >> 8;",
898 },
899 { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
900 "R[n] = UR[n] >> 16;",
901 },
902
903 { "", "", "sleep", "0000000000011011",
904 "trap (0xc3, R0, memory, maskl, maskw, little_endian);",
905 "nia = PC;",
906 },
907
908 { "n", "", "stc GBR,<REG_N>", "0000nnnn00010010",
909 "R[n] = GBR;",
910 },
911 { "n", "", "stc SR,<REG_N>", "0000nnnn00000010",
912 "R[n] = GET_SR ();",
913 },
914 { "n", "", "stc VBR,<REG_N>", "0000nnnn00100010",
915 "R[n] = VBR;",
916 },
917 { "n", "", "stc SSR,<REG_N>", "0000nnnn00110010",
918 "R[n] = SSR;",
919 },
920 { "n", "", "stc SPC,<REG_N>", "0000nnnn01000010",
921 "R[n] = SPC;",
922 },
923 { "n", "", "stc R0_BANK,<REG_N>", "0000nnnn10000010",
924 "R[n] = Rn_BANK (0);",
925 },
926 { "n", "", "stc R1_BANK,<REG_N>", "0000nnnn10010010",
927 "R[n] = Rn_BANK (1);",
928 },
929 { "n", "", "stc R2_BANK,<REG_N>", "0000nnnn10100010",
930 "R[n] = Rn_BANK (2);",
931 },
932 { "n", "", "stc R3_BANK,<REG_N>", "0000nnnn10110010",
933 "R[n] = Rn_BANK (3);",
934 },
935 { "n", "", "stc R4_BANK,<REG_N>", "0000nnnn11000010",
936 "R[n] = Rn_BANK (4);",
937 },
938 { "n", "", "stc R5_BANK,<REG_N>", "0000nnnn11010010",
939 "R[n] = Rn_BANK (5);",
940 },
941 { "n", "", "stc R6_BANK,<REG_N>", "0000nnnn11100010",
942 "R[n] = Rn_BANK (6);",
943 },
944 { "n", "", "stc R7_BANK,<REG_N>", "0000nnnn11110010",
945 "R[n] = Rn_BANK (7);",
946 },
947 { "n", "n", "stc.l GBR,@-<REG_N>", "0100nnnn00010011",
948 "MA (1);",
949 "R[n] -= 4;",
950 "WLAT (R[n], GBR);;",
951 },
952 { "n", "n", "stc.l SR,@-<REG_N>", "0100nnnn00000011",
953 "MA (1);",
954 "R[n] -= 4;",
955 "WLAT (R[n], GET_SR());",
956 },
957 { "n", "n", "stc.l VBR,@-<REG_N>", "0100nnnn00100011",
958 "MA (1);",
959 "R[n] -= 4;",
960 "WLAT (R[n], VBR);",
961 },
962 { "n", "n", "stc.l SSR,@-<REG_N>", "0100nnnn00110011",
963 "MA (1);",
964 "R[n] -= 4;",
965 "WLAT (R[n], SSR);",
966 },
967 { "n", "n", "stc.l SPC,@-<REG_N>", "0100nnnn01000011",
968 "MA (1);",
969 "R[n] -= 4;",
970 "WLAT (R[n], SPC);",
971 },
972 { "n", "", "stc R0_BANK,@-<REG_N>", "0100nnnn10000010",
973 "MA (1);",
974 "R[n] -= 4;",
975 "WLAT (R[n], Rn_BANK (0));",
976 },
977 { "n", "", "stc R1_BANK,@-<REG_N>", "0100nnnn10010010",
978 "MA (1);",
979 "R[n] -= 4;",
980 "WLAT (R[n], Rn_BANK (1));",
981 },
982 { "n", "", "stc R2_BANK,@-<REG_N>", "0100nnnn10100010",
983 "MA (1);",
984 "R[n] -= 4;",
985 "WLAT (R[n], Rn_BANK (2));",
986 },
987 { "n", "", "stc R3_BANK,@-<REG_N>", "0100nnnn10110010",
988 "MA (1);",
989 "R[n] -= 4;",
990 "WLAT (R[n], Rn_BANK (3));",
991 },
992 { "n", "", "stc R4_BANK,@-<REG_N>", "0100nnnn11000010",
993 "MA (1);",
994 "R[n] -= 4;",
995 "WLAT (R[n], Rn_BANK (4));",
996 },
997 { "n", "", "stc R5_BANK,@-<REG_N>", "0100nnnn11010010",
998 "MA (1);",
999 "R[n] -= 4;",
1000 "WLAT (R[n], Rn_BANK (5));",
1001 },
1002 { "n", "", "stc R6_BANK,@-<REG_N>", "0100nnnn11100010",
1003 "MA (1);",
1004 "R[n] -= 4;",
1005 "WLAT (R[n], Rn_BANK (6));",
1006 },
1007 { "n", "", "stc R7_BANK,@-<REG_N>", "0100nnnn11110010",
1008 "MA (1);",
1009 "R[n] -= 4;",
1010 "WLAT (R[n], Rn_BANK (7));",
1011 },
1012
1013 /* sh3e */
1014 { "", "", "sts FPUL,<REG_N>", "0000nnnn01011010",
1015 "R[n] = FPUL;",
1016 },
1017 /* sh3e */
1018 { "", "", "sts.l FPUL,@-<REG_N>", "0100nnnn01010010",
1019 "MA (1);",
1020 "R[n] -= 4;",
1021 "WLAT (R[n], FPUL);",
1022 },
1023 /* sh3e */
1024 { "", "", "sts FPSCR,<REG_N>", "0000nnnn01101010",
1025 "R[n] = GET_FPSCR ();",
1026 },
1027 /* sh3e */
1028 { "", "", "sts.l FPSCR,@-<REG_N>", "0100nnnn01100010",
1029 "MA (1);",
1030 "R[n] -= 4;",
1031 "WLAT (R[n], GET_FPSCR ());",
1032 },
1033
1034 { "n", "", "sts MACH,<REG_N>", "0000nnnn00001010",
1035 "R[n] = MACH;",
1036 },
1037 { "n", "", "sts MACL,<REG_N>", "0000nnnn00011010",
1038 "R[n] = MACL;",
1039 },
1040 { "n", "", "sts PR,<REG_N>", "0000nnnn00101010",
1041 "R[n] = PR;",
1042 },
1043 { "n", "n", "sts.l MACH,@-<REG_N>", "0100nnnn00000010",
1044 "MA (1);",
1045 "R[n] -= 4;",
1046 "WLAT (R[n], MACH);",
1047 },
1048 { "n", "n", "sts.l MACL,@-<REG_N>", "0100nnnn00010010",
1049 "MA (1);",
1050 "R[n] -= 4;",
1051 "WLAT (R[n], MACL);",
1052 },
1053 { "n", "n", "sts.l PR,@-<REG_N>", "0100nnnn00100010",
1054 "MA (1);",
1055 "R[n] -= 4;",
1056 "WLAT (R[n], PR);",
1057 },
1058
1059 { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1060 "R[n] -= R[m];",
1061 },
1062
1063 { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1064 "ult = R[n] - T;",
1065 "SET_SR_T (ult > R[n]);",
1066 "R[n] = ult - R[m];",
1067 "SET_SR_T (T || (R[n] > ult));",
1068 },
1069
1070 { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1071 "ult = R[n] - R[m];",
1072 "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1073 "R[n] = ult;",
1074 },
1075
1076 { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1077 "R[n] = ((R[m] & 0xffff0000)",
1078 " | ((R[m] << 8) & 0xff00)",
1079 " | ((R[m] >> 8) & 0x00ff));",
1080 },
1081 { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1082 "R[n] = (((R[m] << 16) & 0xffff0000)",
1083 " | ((R[m] >> 16) & 0x00ffff));",
1084 },
1085
1086 { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1087 "MA (1);",
1088 "ult = RBAT(R[n]);",
1089 "SET_SR_T (ult == 0);",
1090 "WBAT(R[n],ult|0x80);",
1091 },
1092
1093 { "0", "", "trapa #<imm>", "11000011i8*1....",
1094 #if 0
1095 /* SH-[12] */
1096 "long imm = 0xff & i;",
1097 "if (i==0xc3)",
1098 " PC-=2;",
1099 "if (i<20||i==34||i==0xc3)",
1100 " trap(i,R,memory,maskl,maskw,little_endian);",
1101 "else {",
1102 " R[15]-=4;",
1103 " WLAT(R[15],GET_SR());",
1104 " R[15]-=4;",
1105 " WLAT(R[15],PC+2);",
1106 " PC=RLAT(VBR+(imm<<2))-2;",
1107 "}",
1108 #else
1109 "if (i == 0xc3)",
1110 " {",
1111 " nia = PC;",
1112 " trap (i, R, memory, maskl, maskw, little_endian);",
1113 " }",
1114 "else if (i < 20 || i==34 || i==0xc3)",
1115 " trap (i, R, memory, maskl, maskw, little_endian);",
1116 "else if (!SR_BL) {",
1117 " /* FIXME: TRA = (imm << 2); */",
1118 " SSR = GET_SR();",
1119 " SPC = PC + 2;",
1120 " SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1121 " /* FIXME: EXPEVT = 0x00000160; */",
1122 " nia = VBR + 0x00000100;",
1123 "}",
1124 #endif
1125 },
1126
1127 { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1128 "SET_SR_T ((R[n] & R[m]) == 0);",
1129 },
1130 { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1131 "SET_SR_T ((R0 & i) == 0);",
1132 },
1133 { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1134 "MA (1);",
1135 "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1136 },
1137
1138 { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1139 "R0 ^= i;",
1140 },
1141 { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1142 "R[n] ^= R[m];",
1143 },
1144 { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1145 "MA (1);",
1146 "ult = RBAT (GBR+R0);",
1147 "ult ^= i;",
1148 "WBAT (GBR + R0, ult);",
1149 },
1150
1151 { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1152 "R[n] = (((R[n] >> 16) & 0xffff)",
1153 " | ((R[m] << 16) & 0xffff0000));",
1154 },
1155
1156 {0, 0}};
1157
1158 /* Tables of things to put into enums for sh-opc.h */
1159 static char *nibble_type_list[] =
1160 {
1161 "HEX_0",
1162 "HEX_1",
1163 "HEX_2",
1164 "HEX_3",
1165 "HEX_4",
1166 "HEX_5",
1167 "HEX_6",
1168 "HEX_7",
1169 "HEX_8",
1170 "HEX_9",
1171 "HEX_A",
1172 "HEX_B",
1173 "HEX_C",
1174 "HEX_D",
1175 "HEX_E",
1176 "HEX_F",
1177 "REG_N",
1178 "REG_M",
1179 "BRANCH_12",
1180 "BRANCH_8",
1181 "DISP_8",
1182 "DISP_4",
1183 "IMM_4",
1184 "IMM_4BY2",
1185 "IMM_4BY4",
1186 "PCRELIMM_8BY2",
1187 "PCRELIMM_8BY4",
1188 "IMM_8",
1189 "IMM_8BY2",
1190 "IMM_8BY4",
1191 0
1192 };
1193 static
1194 char *arg_type_list[] =
1195 {
1196 "A_END",
1197 "A_BDISP12",
1198 "A_BDISP8",
1199 "A_DEC_M",
1200 "A_DEC_N",
1201 "A_DISP_GBR",
1202 "A_DISP_PC",
1203 "A_DISP_REG_M",
1204 "A_DISP_REG_N",
1205 "A_GBR",
1206 "A_IMM",
1207 "A_INC_M",
1208 "A_INC_N",
1209 "A_IND_M",
1210 "A_IND_N",
1211 "A_IND_R0_REG_M",
1212 "A_IND_R0_REG_N",
1213 "A_MACH",
1214 "A_MACL",
1215 "A_PR",
1216 "A_R0",
1217 "A_R0_GBR",
1218 "A_REG_M",
1219 "A_REG_N",
1220 "A_SR",
1221 "A_VBR",
1222 "A_SSR",
1223 "A_SPC",
1224 0,
1225 };
1226
1227 static void
1228 make_enum_list (name, s)
1229 char *name;
1230 char **s;
1231 {
1232 int i = 1;
1233 printf ("typedef enum {\n");
1234 while (*s)
1235 {
1236 printf ("\t%s,\n", *s);
1237 s++;
1238 i++;
1239 }
1240 printf ("} %s;\n", name);
1241 }
1242
1243 static int
1244 qfunc (a, b)
1245 op *a;
1246 op *b;
1247 {
1248 char bufa[9];
1249 char bufb[9];
1250 memcpy (bufa, a->code, 4);
1251 memcpy (bufa + 4, a->code + 12, 4);
1252 bufa[8] = 0;
1253
1254 memcpy (bufb, b->code, 4);
1255 memcpy (bufb + 4, b->code + 12, 4);
1256 bufb[8] = 0;
1257 return (strcmp (bufa, bufb));
1258 }
1259
1260 static void
1261 sorttab ()
1262 {
1263 op *p = tab;
1264 int len = 0;
1265
1266 while (p->name)
1267 {
1268 p++;
1269 len++;
1270 }
1271 qsort (tab, len, sizeof (*p), qfunc);
1272 }
1273
1274 static void
1275 printonmatch (ptr, a, rep)
1276 char **ptr;
1277 char *a;
1278 char *rep;
1279 {
1280 int l = strlen (a);
1281 if (strncmp (*ptr, a, l) == 0)
1282 {
1283 printf ("%s", rep);
1284 *ptr += l;
1285 if (**ptr)
1286 printf (",");
1287 }
1288 }
1289
1290
1291 static
1292 void
1293 think (o)
1294 op *o;
1295 {
1296 char *n;
1297 char *p;
1298
1299 printf ("{\"");
1300 n = o->name;
1301 while (*n && *n != ' ')
1302 {
1303 printf ("%c", *n);
1304 n++;
1305 }
1306 printf ("\",{");
1307
1308 p = n;
1309
1310 if (!*p)
1311 {
1312 printf ("0");
1313 }
1314 while (*p)
1315 {
1316 while (*p == ',' || *p == ' ')
1317 p++;
1318 printonmatch (&p, "#<imm>", "A_IMM");
1319 printonmatch (&p, "R0", "A_R0");
1320 printonmatch (&p, "<REG_N>", "A_REG_N");
1321 printonmatch (&p, "@<REG_N>+", "A_INC_N");
1322 printonmatch (&p, "@<REG_N>", "A_IND_N");
1323 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
1324 printonmatch (&p, "<REG_M>", " A_REG_M");
1325 printonmatch (&p, "@<REG_M>+", "A_INC_M");
1326 printonmatch (&p, "@<REG_M>", "A_IND_M");
1327 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
1328 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
1329 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
1330 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
1331 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
1332 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
1333 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
1334 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
1335 printonmatch (&p, "<bdisp8>", "A_BDISP8");
1336 printonmatch (&p, "<bdisp12>", "A_BDISP12");
1337 printonmatch (&p, "SR", "A_SR");
1338 printonmatch (&p, "GBR", "A_GBR");
1339 printonmatch (&p, "VBR", "A_VBR");
1340 printonmatch (&p, "SSR", "A_SSR");
1341 printonmatch (&p, "SPC", "A_SPC");
1342 printonmatch (&p, "MACH", "A_MACH");
1343 printonmatch (&p, "MACL", "A_MACL");
1344 printonmatch (&p, "PR", "A_PR");
1345
1346 }
1347 printf ("},{");
1348
1349 p = o->code;
1350 while (*p)
1351 {
1352 printonmatch (&p, "0000", "HEX_0");
1353 printonmatch (&p, "0001", "HEX_1");
1354 printonmatch (&p, "0010", "HEX_2");
1355 printonmatch (&p, "0011", "HEX_3");
1356 printonmatch (&p, "0100", "HEX_4");
1357 printonmatch (&p, "0101", "HEX_5");
1358 printonmatch (&p, "0110", "HEX_6");
1359 printonmatch (&p, "0111", "HEX_7");
1360
1361 printonmatch (&p, "1000", "HEX_8");
1362 printonmatch (&p, "1001", "HEX_9");
1363 printonmatch (&p, "1010", "HEX_A");
1364 printonmatch (&p, "1011", "HEX_B");
1365 printonmatch (&p, "1100", "HEX_C");
1366 printonmatch (&p, "1101", "HEX_D");
1367 printonmatch (&p, "1110", "HEX_E");
1368 printonmatch (&p, "1111", "HEX_F");
1369 printonmatch (&p, "i8*1....", "IMM_8");
1370 printonmatch (&p, "i4*1", "IMM_4");
1371 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
1372 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
1373 printonmatch (&p, "i8*2....", "IMM_8BY2");
1374 printonmatch (&p, "i4*2", "IMM_4BY2");
1375 printonmatch (&p, "i8*4....", "IMM_8BY4");
1376 printonmatch (&p, "i4*4", "IMM_4BY4");
1377 printonmatch (&p, "i12.........", "BRANCH_12");
1378 printonmatch (&p, "i8p1....", "BRANCH_8");
1379 printonmatch (&p, "nnnn", "REG_N");
1380 printonmatch (&p, "mmmm", "REG_M");
1381
1382 }
1383 printf ("}},\n");
1384 }
1385
1386 static void
1387 gengastab ()
1388 {
1389 op *p;
1390 sorttab ();
1391 for (p = tab; p->name; p++)
1392 {
1393 printf ("%s %-30s\n", p->code, p->name);
1394 }
1395
1396
1397 }
1398
1399
1400 static void
1401 genopc ()
1402 {
1403 op *p;
1404 make_enum_list ("sh_nibble_type", nibble_type_list);
1405 make_enum_list ("sh_arg_type", arg_type_list);
1406
1407 printf ("typedef struct {\n");
1408 printf ("char *name;\n");
1409 printf ("sh_arg_type arg[3];\n");
1410 printf ("sh_nibble_type nibbles[4];\n");
1411 printf ("} sh_opcode_info;\n");
1412 printf ("#ifdef DEFINE_TABLE\n");
1413 printf ("sh_opcode_info sh_table[]={\n");
1414 for (p = tab; p->name; p++)
1415 {
1416 printf ("\n/* %s %-20s*/", p->code, p->name);
1417 think (p);
1418 }
1419 printf ("0};\n");
1420 printf ("#endif\n");
1421 }
1422
1423
1424
1425
1426
1427
1428 /* Convert a string of 4 binary digits into an int */
1429
1430 static
1431 int
1432 bton (s)
1433 char *s;
1434
1435 {
1436 int n = 0;
1437 int v = 8;
1438 while (v)
1439 {
1440 if (*s == '1')
1441 n |= v;
1442 v >>= 1;
1443 s++;
1444 }
1445 return n;
1446 }
1447
1448 static unsigned char table[1 << 16];
1449
1450 /* Take an opcode expand all varying fields in it out and fill all the
1451 right entries in 'table' with the opcode index*/
1452
1453 static void
1454 expand_opcode (shift, val, i, s)
1455 int shift;
1456 int val;
1457 int i;
1458 char *s;
1459 {
1460 int j;
1461
1462 if (*s == 0)
1463 {
1464 table[val] = i;
1465 }
1466 else
1467 {
1468 switch (s[0])
1469 {
1470
1471 case '0':
1472 case '1':
1473 {
1474
1475 int n = bton (s);
1476 if (n >= 0)
1477 {
1478 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
1479 }
1480 break;
1481 }
1482 case 'n':
1483 case 'm':
1484 for (j = 0; j < 16; j++)
1485 {
1486 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1487
1488 }
1489 break;
1490
1491 default:
1492 for (j = 0; j < (1 << (shift + 4)); j++)
1493 {
1494 table[val | j] = i;
1495 }
1496 }
1497 }
1498 }
1499
1500 /* Print the jump table used to index an opcode into a switch
1501 statement entry. */
1502
1503 static void
1504 dumptable ()
1505 {
1506 int lump = 256;
1507 int online = 16;
1508
1509 int i = 0;
1510
1511 while (i < 1 << 16)
1512 {
1513 int j = 0;
1514
1515 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
1516
1517 while (j < lump)
1518 {
1519 int k = 0;
1520 while (k < online)
1521 {
1522 printf ("%2d", table[i + j + k]);
1523 if (j + k < lump)
1524 printf (",");
1525
1526 k++;
1527 }
1528 j += k;
1529 printf ("\n");
1530 }
1531 i += j;
1532 printf ("};\n");
1533 }
1534
1535 }
1536
1537
1538 static void
1539 filltable ()
1540 {
1541 op *p;
1542 int index = 1;
1543
1544 sorttab ();
1545 for (p = tab; p->name; p++)
1546 {
1547 p->index = index++;
1548 expand_opcode (12, 0, p->index, p->code);
1549 }
1550 }
1551
1552 static void
1553 gensim ()
1554 {
1555 op *p;
1556 int j;
1557
1558 printf ("{\n");
1559 printf (" switch (jump_table[iword]) {\n");
1560
1561 for (p = tab; p->name; p++)
1562 {
1563 int sextbit = -1;
1564 int needm = 0;
1565 int needn = 0;
1566
1567 char *s = p->code;
1568
1569 printf (" /* %s %s */\n", p->name, p->code);
1570 printf (" case %d: \n", p->index);
1571
1572 printf (" {\n");
1573 while (*s)
1574 {
1575 switch (*s)
1576 {
1577 case '0':
1578 case '1':
1579 case '.':
1580 s += 4;
1581 break;
1582 case 'n':
1583 printf (" int n = (iword >>8) & 0xf;\n");
1584 needn = 1;
1585 s += 4;
1586 break;
1587 case 'm':
1588 printf (" int m = (iword >>4) & 0xf;\n");
1589 needm = 1;
1590 s += 4;
1591
1592 break;
1593
1594 case 'i':
1595 printf (" int i = (iword & 0x");
1596
1597 switch (s[1])
1598 {
1599 case '4':
1600 printf ("f");
1601 break;
1602 case '8':
1603 printf ("ff");
1604 break;
1605 case '1':
1606 sextbit = 12;
1607
1608 printf ("fff");
1609 break;
1610 }
1611 printf (")");
1612
1613 switch (s[3])
1614 {
1615 case '1':
1616 break;
1617 case '2':
1618 printf ("<<1");
1619 break;
1620 case '4':
1621 printf ("<<2");
1622 break;
1623 }
1624 printf (";\n");
1625 s += 4;
1626 }
1627 }
1628 if (sextbit > 0)
1629 {
1630 printf (" i = (i ^ (1<<%d))-(1<<%d);\n",
1631 sextbit - 1, sextbit - 1);
1632 }
1633
1634 if (needm && needn)
1635 printf (" TB(m,n);\n");
1636 else if (needm)
1637 printf (" TL(m);\n");
1638 else if (needn)
1639 printf (" TL(n);\n");
1640
1641 {
1642 /* Do the refs */
1643 char *r;
1644 for (r = p->refs; *r; r++)
1645 {
1646 if (*r == '0') printf(" CREF(0);\n");
1647 if (*r == 'n') printf(" CREF(n);\n");
1648 if (*r == 'm') printf(" CREF(m);\n");
1649 }
1650 }
1651
1652 printf (" {\n");
1653 for (j = 0; j < MAX_NR_STUFF; j++)
1654 {
1655 if (p->stuff[j])
1656 {
1657 printf (" %s\n", p->stuff[j]);
1658 }
1659 }
1660 printf (" }\n");
1661
1662 {
1663 /* Do the defs */
1664 char *r;
1665 for (r = p->defs; *r; r++)
1666 {
1667 if (*r == '0') printf(" CDEF(0);\n");
1668 if (*r == 'n') printf(" CDEF(n);\n");
1669 if (*r == 'm') printf(" CDEF(m);\n");
1670 }
1671 }
1672
1673 printf (" break;\n");
1674 printf (" }\n");
1675 }
1676 printf (" default:\n");
1677 printf (" {\n");
1678 printf (" saved_state.asregs.exception = SIGILL;\n");
1679 printf (" }\n");
1680 printf (" }\n");
1681 printf ("}\n");
1682 }
1683
1684
1685 static void
1686 gendefines ()
1687 {
1688 op *p;
1689 filltable();
1690 for (p = tab; p->name; p++)
1691 {
1692 char *s = p->name;
1693 printf ("#define OPC_");
1694 while (*s) {
1695 if (isupper(*s))
1696 *s = tolower(*s);
1697 if (isalpha(*s)) printf("%c", *s);
1698 if (*s == ' ') printf("_");
1699 if (*s == '@') printf("ind_");
1700 if (*s == ',') printf("_");
1701 s++;
1702 }
1703 printf(" %d\n",p->index);
1704 }
1705 }
1706
1707 int
1708 main (ac, av)
1709 int ac;
1710 char **av;
1711 {
1712 /* verify the table before anything else */
1713 {
1714 op *p;
1715 for (p = tab; p->name; p++)
1716 {
1717 /* check that the code field contains 16 bits */
1718 if (strlen (p->code) != 16)
1719 {
1720 fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
1721 p->code, strlen (p->code), p->name);
1722 abort ();
1723 }
1724 }
1725 }
1726
1727 /* now generate the requested data */
1728 if (ac > 1)
1729 {
1730 if (strcmp (av[1], "-t") == 0)
1731 {
1732 gengastab ();
1733 }
1734 else if (strcmp (av[1], "-d") == 0)
1735 {
1736 gendefines ();
1737 }
1738 else if (strcmp (av[1], "-s") == 0)
1739 {
1740 filltable ();
1741 dumptable ();
1742
1743 }
1744 else if (strcmp (av[1], "-x") == 0)
1745 {
1746 filltable ();
1747 gensim ();
1748 }
1749 }
1750 else
1751 {
1752 genopc ();
1753 }
1754 return 0;
1755 }