First commit
[clinton/Virtual-Jaguar-Rx.git] / src / m68000 / readcpu.c
1 /*
2 * UAE - The Un*x Amiga Emulator - CPU core
3 *
4 * Read 68000 CPU specs from file "table68k"
5 *
6 * Copyright 1995,1996 Bernd Schmidt
7 *
8 * Adaptation to Hatari by Thomas Huth
9 * Adaptation to Virtual Jaguar by James Hammons
10 *
11 * This file is distributed under the GNU Public License, version 3 or at
12 * your option any later version. Read the file GPLv3 for details.
13 */
14
15
16 /* 2008/04/26 [NP] Handle sz_byte for Areg as a valid srcmode if current instruction is a MOVE */
17 /* (e.g. move.b a1,(a0) ($1089)) (fix Blood Money on Superior 65) */
18
19
20 //const char ReadCpu_fileid[] = "Hatari readcpu.c : " __DATE__ " " __TIME__;
21
22 #include <ctype.h>
23 #include <string.h>
24
25 #include "readcpu.h"
26
27 int nr_cpuop_funcs;
28
29 const struct mnemolookup lookuptab[] = {
30 { i_ILLG, "ILLEGAL" },
31 { i_OR, "OR" },
32 { i_CHK, "CHK" },
33 { i_CHK2, "CHK2" },
34 { i_AND, "AND" },
35 { i_EOR, "EOR" },
36 { i_ORSR, "ORSR" },
37 { i_ANDSR, "ANDSR" },
38 { i_EORSR, "EORSR" },
39 { i_SUB, "SUB" },
40 { i_SUBA, "SUBA" },
41 { i_SUBX, "SUBX" },
42 { i_SBCD, "SBCD" },
43 { i_ADD, "ADD" },
44 { i_ADDA, "ADDA" },
45 { i_ADDX, "ADDX" },
46 { i_ABCD, "ABCD" },
47 { i_NEG, "NEG" },
48 { i_NEGX, "NEGX" },
49 { i_NBCD, "NBCD" },
50 { i_CLR, "CLR" },
51 { i_NOT, "NOT" },
52 { i_TST, "TST" },
53 { i_BTST, "BTST" },
54 { i_BCHG, "BCHG" },
55 { i_BCLR, "BCLR" },
56 { i_BSET, "BSET" },
57 { i_CMP, "CMP" },
58 { i_CMPM, "CMPM" },
59 { i_CMPA, "CMPA" },
60 { i_MVPRM, "MVPRM" },
61 { i_MVPMR, "MVPMR" },
62 { i_MOVE, "MOVE" },
63 { i_MOVEA, "MOVEA" },
64 { i_MVSR2, "MVSR2" },
65 { i_MV2SR, "MV2SR" },
66 { i_SWAP, "SWAP" },
67 { i_EXG, "EXG" },
68 { i_EXT, "EXT" },
69 { i_MVMEL, "MVMEL" },
70 { i_MVMLE, "MVMLE" },
71 { i_TRAP, "TRAP" },
72 { i_MVR2USP, "MVR2USP" },
73 { i_MVUSP2R, "MVUSP2R" },
74 { i_NOP, "NOP" },
75 { i_RESET, "RESET" },
76 { i_RTE, "RTE" },
77 { i_RTD, "RTD" },
78 { i_LINK, "LINK" },
79 { i_UNLK, "UNLK" },
80 { i_RTS, "RTS" },
81 { i_STOP, "STOP" },
82 { i_TRAPV, "TRAPV" },
83 { i_RTR, "RTR" },
84 { i_JSR, "JSR" },
85 { i_JMP, "JMP" },
86 { i_BSR, "BSR" },
87 { i_Bcc, "Bcc" },
88 { i_LEA, "LEA" },
89 { i_PEA, "PEA" },
90 { i_DBcc, "DBcc" },
91 { i_Scc, "Scc" },
92 { i_DIVU, "DIVU" },
93 { i_DIVS, "DIVS" },
94 { i_MULU, "MULU" },
95 { i_MULS, "MULS" },
96 { i_ASR, "ASR" },
97 { i_ASL, "ASL" },
98 { i_LSR, "LSR" },
99 { i_LSL, "LSL" },
100 { i_ROL, "ROL" },
101 { i_ROR, "ROR" },
102 { i_ROXL, "ROXL" },
103 { i_ROXR, "ROXR" },
104 { i_ASRW, "ASRW" },
105 { i_ASLW, "ASLW" },
106 { i_LSRW, "LSRW" },
107 { i_LSLW, "LSLW" },
108 { i_ROLW, "ROLW" },
109 { i_RORW, "RORW" },
110 { i_ROXLW, "ROXLW" },
111 { i_ROXRW, "ROXRW" },
112
113 { i_MOVE2C, "MOVE2C" },
114 { i_MOVEC2, "MOVEC2" },
115 { i_CAS, "CAS" },
116 { i_CAS2, "CAS2" },
117 { i_MULL, "MULL" },
118 { i_DIVL, "DIVL" },
119 { i_BFTST, "BFTST" },
120 { i_BFEXTU, "BFEXTU" },
121 { i_BFCHG, "BFCHG" },
122 { i_BFEXTS, "BFEXTS" },
123 { i_BFCLR, "BFCLR" },
124 { i_BFFFO, "BFFFO" },
125 { i_BFSET, "BFSET" },
126 { i_BFINS, "BFINS" },
127 { i_PACK, "PACK" },
128 { i_UNPK, "UNPK" },
129 { i_TAS, "TAS" },
130 { i_BKPT, "BKPT" },
131 { i_CALLM, "CALLM" },
132 { i_RTM, "RTM" },
133 { i_TRAPcc, "TRAPcc" },
134 { i_MOVES, "MOVES" },
135 { i_FPP, "FPP" },
136 { i_FDBcc, "FDBcc" },
137 { i_FScc, "FScc" },
138 { i_FTRAPcc, "FTRAPcc" },
139 { i_FBcc, "FBcc" },
140 { i_FBcc, "FBcc" },
141 { i_FSAVE, "FSAVE" },
142 { i_FRESTORE, "FRESTORE" },
143
144 { i_CINVL, "CINVL" },
145 { i_CINVP, "CINVP" },
146 { i_CINVA, "CINVA" },
147 { i_CPUSHL, "CPUSHL" },
148 { i_CPUSHP, "CPUSHP" },
149 { i_CPUSHA, "CPUSHA" },
150 { i_MOVE16, "MOVE16" },
151
152 { i_MMUOP, "MMUOP" },
153 { i_ILLG, "" },
154 };
155
156
157 struct instr * table68k;
158
159
160 STATIC_INLINE amodes mode_from_str(const char * str)
161 {
162 if (strncmp (str, "Dreg", 4) == 0) return Dreg;
163 if (strncmp (str, "Areg", 4) == 0) return Areg;
164 if (strncmp (str, "Aind", 4) == 0) return Aind;
165 if (strncmp (str, "Apdi", 4) == 0) return Apdi;
166 if (strncmp (str, "Aipi", 4) == 0) return Aipi;
167 if (strncmp (str, "Ad16", 4) == 0) return Ad16;
168 if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
169 if (strncmp (str, "absw", 4) == 0) return absw;
170 if (strncmp (str, "absl", 4) == 0) return absl;
171 if (strncmp (str, "PC16", 4) == 0) return PC16;
172 if (strncmp (str, "PC8r", 4) == 0) return PC8r;
173 if (strncmp (str, "Immd", 4) == 0) return imm;
174
175 abort();
176 return 0;
177 }
178
179
180 STATIC_INLINE amodes mode_from_mr(int mode, int reg)
181 {
182 switch (mode)
183 {
184 case 0: return Dreg;
185 case 1: return Areg;
186 case 2: return Aind;
187 case 3: return Aipi;
188 case 4: return Apdi;
189 case 5: return Ad16;
190 case 6: return Ad8r;
191 case 7:
192 switch (reg)
193 {
194 case 0: return absw;
195 case 1: return absl;
196 case 2: return PC16;
197 case 3: return PC8r;
198 case 4: return imm;
199 case 5:
200 case 6:
201 case 7: return am_illg;
202 }
203 }
204
205 abort();
206 return 0;
207 }
208
209
210 static void build_insn(int insn)
211 {
212 int find = -1;
213 int variants;
214 int isjmp = 0;
215 struct instr_def id;
216 const char * opcstr;
217 int j;
218
219 int flaglive = 0, flagdead = 0;
220 id = defs68k[insn];
221
222 /* Note: We treat anything with unknown flags as a jump. That
223 is overkill, but "the programmer" was lazy quite often, and
224 *this* programmer can't be bothered to work out what can and
225 can't trap. Usually, this will be overwritten with the gencomp
226 based information, anyway. */
227
228 for(j=0; j<5; j++)
229 {
230 switch (id.flaginfo[j].flagset)
231 {
232 case fa_unset: break;
233 case fa_isjmp: isjmp = 1; break;
234 case fa_isbranch: isjmp = 1; break;
235 case fa_zero: flagdead |= 1 << j; break;
236 case fa_one: flagdead |= 1 << j; break;
237 case fa_dontcare: flagdead |= 1 << j; break;
238 case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
239 case fa_set: flagdead |= 1 << j; break;
240 }
241 }
242
243 out1:
244 for(j=0; j<5; j++)
245 {
246 switch (id.flaginfo[j].flaguse)
247 {
248 case fu_unused: break;
249 case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
250 case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
251 case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
252 case fu_used: flaglive |= 1 << j; break;
253 }
254 }
255
256 opcstr = id.opcstr;
257
258 for(variants=0; variants<(1 << id.n_variable); variants++)
259 {
260 int bitcnt[lastbit];
261 int bitval[lastbit];
262 int bitpos[lastbit];
263 int i;
264 uint16_t opc = id.bits;
265 uint16_t msk, vmsk;
266 int pos = 0;
267 int mnp = 0;
268 int bitno = 0;
269 char mnemonic[10];
270
271 wordsizes sz = sz_long;
272 int srcgather = 0, dstgather = 0;
273 int usesrc = 0, usedst = 0;
274 int srctype = 0;
275 int srcpos = -1, dstpos = -1;
276
277 amodes srcmode = am_unknown, destmode = am_unknown;
278 int srcreg = -1, destreg = -1;
279
280 for(i=0; i<lastbit; i++)
281 bitcnt[i] = bitval[i] = 0;
282
283 vmsk = 1 << id.n_variable;
284
285 for(i=0, msk=0x8000; i<16; i++, msk >>= 1)
286 {
287 if (!(msk & id.mask))
288 {
289 int currbit = id.bitpos[bitno++];
290 int bit_set;
291 vmsk >>= 1;
292 bit_set = (variants & vmsk ? 1 : 0);
293
294 if (bit_set)
295 opc |= msk;
296
297 bitpos[currbit] = 15 - i;
298 bitcnt[currbit]++;
299 bitval[currbit] <<= 1;
300 bitval[currbit] |= bit_set;
301 }
302 }
303
304 if (bitval[bitj] == 0)
305 bitval[bitj] = 8;
306
307 /* first check whether this one does not match after all */
308 if (bitval[bitz] == 3 || bitval[bitC] == 1)
309 continue;
310
311 if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
312 continue;
313
314 /* bitI and bitC get copied to biti and bitc */
315 if (bitcnt[bitI])
316 {
317 bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
318 }
319
320 if (bitcnt[bitC])
321 bitval[bitc] = bitval[bitC];
322
323 pos = 0;
324 while (opcstr[pos] && !isspace((unsigned)opcstr[pos]))
325 {
326 if (opcstr[pos] == '.')
327 {
328 pos++;
329
330 switch (opcstr[pos])
331 {
332 case 'B': sz = sz_byte; break;
333 case 'W': sz = sz_word; break;
334 case 'L': sz = sz_long; break;
335 case 'z':
336 switch (bitval[bitz])
337 {
338 case 0: sz = sz_byte; break;
339 case 1: sz = sz_word; break;
340 case 2: sz = sz_long; break;
341 default: abort();
342 }
343 break;
344 default: abort();
345 }
346 }
347 else
348 {
349 mnemonic[mnp] = opcstr[pos];
350
351 if (mnemonic[mnp] == 'f')
352 {
353 find = -1;
354 switch (bitval[bitf])
355 {
356 case 0: mnemonic[mnp] = 'R'; break;
357 case 1: mnemonic[mnp] = 'L'; break;
358 default: abort();
359 }
360 }
361
362 mnp++;
363 }
364
365 pos++;
366 }
367
368 mnemonic[mnp] = 0;
369
370 /* now, we have read the mnemonic and the size */
371 while (opcstr[pos] && isspace((unsigned)opcstr[pos]))
372 pos++;
373
374 /* A goto a day keeps the D******a away. */
375 if (opcstr[pos] == 0)
376 goto endofline;
377
378 /* parse the source address */
379 usesrc = 1;
380 switch (opcstr[pos++])
381 {
382 case 'D':
383 srcmode = Dreg;
384
385 switch (opcstr[pos++])
386 {
387 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
388 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
389 default: abort();
390 }
391
392 break;
393 case 'A':
394 srcmode = Areg;
395
396 switch (opcstr[pos++])
397 {
398 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
399 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
400 default: abort();
401 }
402
403 switch (opcstr[pos])
404 {
405 case 'p': srcmode = Apdi; pos++; break;
406 case 'P': srcmode = Aipi; pos++; break;
407 }
408 break;
409
410 case 'L':
411 srcmode = absl;
412 break;
413 case '#':
414 switch (opcstr[pos++])
415 {
416 case 'z': srcmode = imm; break;
417 case '0': srcmode = imm0; break;
418 case '1': srcmode = imm1; break;
419 case '2': srcmode = imm2; break;
420 case 'i':
421 srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
422
423 if (CPU_EMU_SIZE < 4)
424 {
425 /* Used for branch instructions */
426 srctype = 1;
427 srcgather = 1;
428 srcpos = bitpos[biti];
429 }
430
431 break;
432 case 'j':
433 srcmode = immi; srcreg = bitval[bitj];
434
435 if (CPU_EMU_SIZE < 3)
436 {
437 /* 1..8 for ADDQ/SUBQ and rotshi insns */
438 srcgather = 1;
439 srctype = 3;
440 srcpos = bitpos[bitj];
441 }
442
443 break;
444 case 'J':
445 srcmode = immi; srcreg = bitval[bitJ];
446
447 if (CPU_EMU_SIZE < 5)
448 {
449 /* 0..15 */
450 srcgather = 1;
451 srctype = 2;
452 srcpos = bitpos[bitJ];
453 }
454
455 break;
456 case 'k':
457 srcmode = immi; srcreg = bitval[bitk];
458
459 if (CPU_EMU_SIZE < 3)
460 {
461 srcgather = 1;
462 srctype = 4;
463 srcpos = bitpos[bitk];
464 }
465
466 break;
467 case 'K':
468 srcmode = immi; srcreg = bitval[bitK];
469
470 if (CPU_EMU_SIZE < 5)
471 {
472 /* 0..15 */
473 srcgather = 1;
474 srctype = 5;
475 srcpos = bitpos[bitK];
476 }
477
478 break;
479 case 'p':
480 srcmode = immi; srcreg = bitval[bitK];
481
482 if (CPU_EMU_SIZE < 5)
483 {
484 /* 0..3 */
485 srcgather = 1;
486 srctype = 7;
487 srcpos = bitpos[bitp];
488 }
489
490 break;
491 default: abort();
492 }
493
494 break;
495 case 'd':
496 srcreg = bitval[bitD];
497 srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
498
499 if (srcmode == am_illg)
500 continue;
501
502 if (CPU_EMU_SIZE < 2
503 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
504 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
505 || srcmode == Apdi))
506 {
507 srcgather = 1;
508 srcpos = bitpos[bitD];
509 }
510
511 if (opcstr[pos] == '[')
512 {
513 pos++;
514
515 if (opcstr[pos] == '!')
516 {
517 /* exclusion */
518 do
519 {
520 pos++;
521
522 if (mode_from_str(opcstr + pos) == srcmode)
523 goto nomatch;
524
525 pos += 4;
526 }
527 while (opcstr[pos] == ',');
528
529 pos++;
530 }
531 else
532 {
533 if (opcstr[pos + 4] == '-')
534 {
535 /* replacement */
536 if (mode_from_str(opcstr + pos) == srcmode)
537 srcmode = mode_from_str(opcstr + pos + 5);
538 else
539 goto nomatch;
540
541 pos += 10;
542 }
543 else
544 {
545 /* normal */
546 while(mode_from_str(opcstr + pos) != srcmode)
547 {
548 pos += 4;
549
550 if (opcstr[pos] == ']')
551 goto nomatch;
552
553 pos++;
554 }
555
556 while(opcstr[pos] != ']')
557 pos++;
558
559 pos++;
560 break;
561 }
562 }
563 }
564
565 /* Some addressing modes are invalid as destination */
566 if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
567 goto nomatch;
568
569 break;
570 case 's':
571 srcreg = bitval[bitS];
572 srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
573
574 if (srcmode == am_illg)
575 continue;
576
577 if (CPU_EMU_SIZE < 2
578 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
579 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
580 || srcmode == Apdi))
581 {
582 srcgather = 1;
583 srcpos = bitpos[bitS];
584 }
585
586 if (opcstr[pos] == '[')
587 {
588 pos++;
589
590 if (opcstr[pos] == '!')
591 {
592 /* exclusion */
593 do
594 {
595 pos++;
596
597 if (mode_from_str(opcstr + pos) == srcmode)
598 goto nomatch;
599
600 pos += 4;
601 }
602 while (opcstr[pos] == ',');
603
604 pos++;
605 }
606 else
607 {
608 if (opcstr[pos + 4] == '-')
609 {
610 /* replacement */
611 if (mode_from_str(opcstr + pos) == srcmode)
612 srcmode = mode_from_str(opcstr + pos + 5);
613 else
614 goto nomatch;
615
616 pos += 10;
617 }
618 else
619 {
620 /* normal */
621 while(mode_from_str(opcstr+pos) != srcmode)
622 {
623 pos += 4;
624
625 if (opcstr[pos] == ']')
626 goto nomatch;
627
628 pos++;
629 }
630
631 while(opcstr[pos] != ']')
632 pos++;
633
634 pos++;
635 }
636 }
637 }
638 break;
639 default: abort();
640 }
641
642 /* safety check - might have changed */
643 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
644 && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
645 && srcmode != Apdi && srcmode != immi)
646 {
647 srcgather = 0;
648 }
649
650 // if (srcmode == Areg && sz == sz_byte)
651 if (srcmode == Areg && sz == sz_byte && strcmp(mnemonic, "MOVE") != 0 ) // [NP] move.b is valid on 68000
652 goto nomatch;
653
654 if (opcstr[pos] != ',')
655 goto endofline;
656
657 pos++;
658
659 /* parse the destination address */
660 usedst = 1;
661
662 switch (opcstr[pos++])
663 {
664 case 'D':
665 destmode = Dreg;
666
667 switch (opcstr[pos++])
668 {
669 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
670 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
671 default: abort();
672 }
673
674 if (dstpos < 0 || dstpos >= 32)
675 abort();
676
677 break;
678 case 'A':
679 destmode = Areg;
680
681 switch (opcstr[pos++])
682 {
683 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
684 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
685 case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
686 default: abort();
687 }
688
689 if (dstpos < 0 || dstpos >= 32)
690 abort();
691
692 switch (opcstr[pos])
693 {
694 case 'p': destmode = Apdi; pos++; break;
695 case 'P': destmode = Aipi; pos++; break;
696 }
697
698 break;
699 case 'L':
700 destmode = absl;
701 break;
702 case '#':
703 switch (opcstr[pos++])
704 {
705 case 'z': destmode = imm; break;
706 case '0': destmode = imm0; break;
707 case '1': destmode = imm1; break;
708 case '2': destmode = imm2; break;
709 case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
710 case 'j': destmode = immi; destreg = bitval[bitj]; break;
711 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
712 case 'k': destmode = immi; destreg = bitval[bitk]; break;
713 case 'K': destmode = immi; destreg = bitval[bitK]; break;
714 default: abort();
715 }
716 break;
717 case 'd':
718 destreg = bitval[bitD];
719 destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
720
721 if (destmode == am_illg)
722 continue;
723
724 if (CPU_EMU_SIZE < 1
725 && (destmode == Areg || destmode == Dreg || destmode == Aind
726 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
727 || destmode == Apdi))
728 {
729 dstgather = 1;
730 dstpos = bitpos[bitD];
731 }
732
733 if (opcstr[pos] == '[')
734 {
735 pos++;
736
737 if (opcstr[pos] == '!')
738 {
739 /* exclusion */
740 do
741 {
742 pos++;
743
744 if (mode_from_str(opcstr + pos) == destmode)
745 goto nomatch;
746
747 pos += 4;
748 }
749 while (opcstr[pos] == ',');
750
751 pos++;
752 }
753 else
754 {
755 if (opcstr[pos+4] == '-')
756 {
757 /* replacement */
758 if (mode_from_str(opcstr + pos) == destmode)
759 destmode = mode_from_str(opcstr + pos + 5);
760 else
761 goto nomatch;
762
763 pos += 10;
764 }
765 else
766 {
767 /* normal */
768 while(mode_from_str(opcstr + pos) != destmode)
769 {
770 pos += 4;
771
772 if (opcstr[pos] == ']')
773 goto nomatch;
774
775 pos++;
776 }
777
778 while(opcstr[pos] != ']')
779 pos++;
780
781 pos++;
782 break;
783 }
784 }
785 }
786
787 /* Some addressing modes are invalid as destination */
788 if (destmode == imm || destmode == PC16 || destmode == PC8r)
789 goto nomatch;
790
791 break;
792 case 's':
793 destreg = bitval[bitS];
794 destmode = mode_from_mr(bitval[bits], bitval[bitS]);
795
796 if (destmode == am_illg)
797 continue;
798 if (CPU_EMU_SIZE < 1
799 && (destmode == Areg || destmode == Dreg || destmode == Aind
800 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
801 || destmode == Apdi))
802 {
803 dstgather = 1;
804 dstpos = bitpos[bitS];
805 }
806
807 if (opcstr[pos] == '[')
808 {
809 pos++;
810
811 if (opcstr[pos] == '!')
812 {
813 /* exclusion */
814 do
815 {
816 pos++;
817
818 if (mode_from_str(opcstr + pos) == destmode)
819 goto nomatch;
820
821 pos += 4;
822 }
823 while (opcstr[pos] == ',');
824
825 pos++;
826 }
827 else
828 {
829 if (opcstr[pos+4] == '-')
830 {
831 /* replacement */
832 if (mode_from_str(opcstr + pos) == destmode)
833 destmode = mode_from_str(opcstr + pos + 5);
834 else
835 goto nomatch;
836
837 pos += 10;
838 }
839 else
840 {
841 /* normal */
842 while (mode_from_str(opcstr + pos) != destmode)
843 {
844 pos += 4;
845
846 if (opcstr[pos] == ']')
847 goto nomatch;
848
849 pos++;
850 }
851
852 while (opcstr[pos] != ']')
853 pos++;
854
855 pos++;
856 }
857 }
858 }
859 break;
860 default: abort();
861 }
862
863 /* safety check - might have changed */
864 if (destmode != Areg && destmode != Dreg && destmode != Aind
865 && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
866 && destmode != Apdi)
867 {
868 dstgather = 0;
869 }
870
871 if (destmode == Areg && sz == sz_byte)
872 goto nomatch;
873 #if 0
874 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
875 dstgather = 0;
876 }
877 #endif
878 endofline:
879 /* now, we have a match */
880 if (table68k[opc].mnemo != i_ILLG)
881 fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
882
883 if (find == -1)
884 {
885 for(find=0; ; find++)
886 {
887 if (strcmp(mnemonic, lookuptab[find].name) == 0)
888 {
889 table68k[opc].mnemo = lookuptab[find].mnemo;
890 break;
891 }
892
893 if (strlen(lookuptab[find].name) == 0)
894 abort();
895 }
896 }
897 else
898 {
899 table68k[opc].mnemo = lookuptab[find].mnemo;
900 }
901
902 table68k[opc].cc = bitval[bitc];
903
904 if (table68k[opc].mnemo == i_BTST
905 || table68k[opc].mnemo == i_BSET
906 || table68k[opc].mnemo == i_BCLR
907 || table68k[opc].mnemo == i_BCHG)
908 {
909 sz = (destmode == Dreg ? sz_long : sz_byte);
910 }
911
912 table68k[opc].size = sz;
913 table68k[opc].sreg = srcreg;
914 table68k[opc].dreg = destreg;
915 table68k[opc].smode = srcmode;
916 table68k[opc].dmode = destmode;
917 table68k[opc].spos = (srcgather ? srcpos : -1);
918 table68k[opc].dpos = (dstgather ? dstpos : -1);
919 table68k[opc].suse = usesrc;
920 table68k[opc].duse = usedst;
921 table68k[opc].stype = srctype;
922 table68k[opc].plev = id.plevel;
923 table68k[opc].clev = id.cpulevel;
924 #if 0
925 for (i = 0; i < 5; i++) {
926 table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
927 table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
928 }
929 #endif
930 table68k[opc].flagdead = flagdead;
931 table68k[opc].flaglive = flaglive;
932 table68k[opc].isjmp = isjmp;
933
934 nomatch:
935 /* FOO! */;
936 }
937 }
938
939
940 void read_table68k(void)
941 {
942 int i;
943 table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
944
945 for(i=0; i<65536; i++)
946 {
947 table68k[i].mnemo = i_ILLG;
948 table68k[i].handler = -1;
949 }
950
951 for(i=0; i<n_defs68k; i++)
952 build_insn(i);
953 }
954
955
956 static int mismatch;
957
958
959 static void handle_merges (long int opcode)
960 {
961 uint16_t smsk;
962 uint16_t dmsk;
963 int sbitdst, dstend;
964 int srcreg, dstreg;
965
966 //0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W s,d[!Areg]
967 //31C3 ->
968 //0011 0001 1100 0011 : DDD = 0, ddd = 7, sss = 0, SSS = 3
969
970 if (table68k[opcode].spos == -1)
971 {
972 sbitdst = 1;
973 smsk = 0;
974 }
975 else
976 {
977 switch (table68k[opcode].stype)
978 {
979 case 0:
980 smsk = 7; sbitdst = 8; break;
981 case 1:
982 smsk = 255; sbitdst = 256; break;
983 case 2:
984 smsk = 15; sbitdst = 16; break;
985 case 3:
986 smsk = 7; sbitdst = 8; break;
987 case 4:
988 smsk = 7; sbitdst = 8; break;
989 case 5:
990 smsk = 63; sbitdst = 64; break;
991 case 7:
992 smsk = 3; sbitdst = 4; break;
993 default:
994 smsk = 0; sbitdst = 0;
995 abort();
996 break;
997 }
998
999 smsk <<= table68k[opcode].spos;
1000 }
1001
1002 if (table68k[opcode].dpos == -1)
1003 {
1004 dmsk = 0;
1005 dstend = 1;
1006 }
1007 else
1008 {
1009 dmsk = 7 << table68k[opcode].dpos;
1010 dstend = 8;
1011 }
1012
1013 for(srcreg=0; srcreg<sbitdst; srcreg++)
1014 {
1015 for(dstreg=0; dstreg<dstend; dstreg++)
1016 {
1017 uint16_t code = opcode;
1018
1019 code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
1020 code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
1021
1022 /* Check whether this is in fact the same instruction.
1023 * The instructions should never differ, except for the
1024 * Bcc.(BW) case. */
1025 if (table68k[code].mnemo != table68k[opcode].mnemo
1026 || table68k[code].size != table68k[opcode].size
1027 || table68k[code].suse != table68k[opcode].suse
1028 || table68k[code].duse != table68k[opcode].duse)
1029 {
1030 mismatch++;
1031 continue;
1032 }
1033
1034 if (table68k[opcode].suse
1035 && (table68k[opcode].spos != table68k[code].spos
1036 || table68k[opcode].smode != table68k[code].smode
1037 || table68k[opcode].stype != table68k[code].stype))
1038 {
1039 mismatch++;
1040 continue;
1041 }
1042
1043 if (table68k[opcode].duse
1044 && (table68k[opcode].dpos != table68k[code].dpos
1045 || table68k[opcode].dmode != table68k[code].dmode))
1046 {
1047 mismatch++;
1048 continue;
1049 }
1050
1051 if (code != opcode)
1052 {
1053 table68k[code].handler = opcode;
1054
1055 #if 0
1056 if (opcode == 0x31C3 || code == 0x31C3)
1057 {
1058 printf("Relocate... ($%04X->$%04X)\n", (uint16_t)opcode, code);
1059 printf(" handler: %08X\n", table68k[code].handler);
1060 printf(" dreg: %i\n", table68k[code].dreg);
1061 printf(" sreg: %i\n", table68k[code].sreg);
1062 printf(" dpos: %i\n", table68k[code].dpos);
1063 printf(" spos: %i\n", table68k[code].spos);
1064 printf(" sduse: %i\n", table68k[code].sduse);
1065 printf("flagdead: %i\n", table68k[code].flagdead);
1066 printf("flaglive: %i\n", table68k[code].flaglive);
1067 }
1068 #endif
1069 /*
1070 long int handler;
1071 unsigned char dreg;
1072 unsigned char sreg;
1073 signed char dpos;
1074 signed char spos;
1075 unsigned char sduse;
1076 int flagdead:8, flaglive:8;
1077 unsigned int mnemo:8;
1078 unsigned int cc:4;
1079 unsigned int plev:2;
1080 unsigned int size:2;
1081 unsigned int smode:5;
1082 unsigned int stype:3;
1083 unsigned int dmode:5;
1084 unsigned int suse:1;
1085 unsigned int duse:1;
1086 unsigned int unused1:1;
1087 unsigned int clev:3;
1088 unsigned int isjmp:1;
1089 unsigned int unused2:4;
1090 */
1091 }
1092 }
1093 }
1094 }
1095
1096
1097 // What this really does is expand the # of handlers, which is why the
1098 // opcode has to be passed into the opcode handler...
1099 // E.g., $F620 maps into $F621-F627 as well; this code does this expansion.
1100 void do_merges(void)
1101 {
1102 long int opcode;
1103 int nr = 0;
1104 mismatch = 0;
1105
1106 for(opcode=0; opcode<65536; opcode++)
1107 {
1108 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
1109 continue;
1110
1111 nr++;
1112 handle_merges(opcode);
1113 }
1114
1115 nr_cpuop_funcs = nr;
1116 }
1117
1118
1119 int get_no_mismatches(void)
1120 {
1121 return mismatch;
1122 }
1123