2 * UAE - The Un*x Amiga Emulator - CPU core
4 * Read 68000 CPU specs from file "table68k"
6 * Copyright 1995,1996 Bernd Schmidt
8 * Adaptation to Hatari by Thomas Huth
9 * Adaptation to Virtual Jaguar by James Hammons
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.
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) */
20 const char ReadCpu_fileid[] = "Hatari readcpu.c : " __DATE__ " " __TIME__;
29 const struct mnemolookup lookuptab[] = {
30 { i_ILLG, "ILLEGAL" },
72 { i_MVR2USP, "MVR2USP" },
73 { i_MVUSP2R, "MVUSP2R" },
110 { i_ROXLW, "ROXLW" },
111 { i_ROXRW, "ROXRW" },
113 { i_MOVE2C, "MOVE2C" },
114 { i_MOVEC2, "MOVEC2" },
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" },
131 { i_CALLM, "CALLM" },
133 { i_TRAPcc, "TRAPcc" },
134 { i_MOVES, "MOVES" },
136 { i_FDBcc, "FDBcc" },
138 { i_FTRAPcc, "FTRAPcc" },
141 { i_FSAVE, "FSAVE" },
142 { i_FRESTORE, "FRESTORE" },
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" },
152 { i_MMUOP, "MMUOP" },
156 struct instr *table68k;
158 STATIC_INLINE amodes mode_from_str (const char *str)
160 if (strncmp (str, "Dreg", 4) == 0) return Dreg;
161 if (strncmp (str, "Areg", 4) == 0) return Areg;
162 if (strncmp (str, "Aind", 4) == 0) return Aind;
163 if (strncmp (str, "Apdi", 4) == 0) return Apdi;
164 if (strncmp (str, "Aipi", 4) == 0) return Aipi;
165 if (strncmp (str, "Ad16", 4) == 0) return Ad16;
166 if (strncmp (str, "Ad8r", 4) == 0) return Ad8r;
167 if (strncmp (str, "absw", 4) == 0) return absw;
168 if (strncmp (str, "absl", 4) == 0) return absl;
169 if (strncmp (str, "PC16", 4) == 0) return PC16;
170 if (strncmp (str, "PC8r", 4) == 0) return PC8r;
171 if (strncmp (str, "Immd", 4) == 0) return imm;
176 STATIC_INLINE amodes mode_from_mr (int mode, int reg)
195 case 7: return am_illg;
202 static void build_insn(int insn)
211 int flaglive = 0, flagdead = 0;
215 /* Note: We treat anything with unknown flags as a jump. That
216 is overkill, but "the programmer" was lazy quite often, and
217 *this* programmer can't be bothered to work out what can and
218 can't trap. Usually, this will be overwritten with the gencomp
219 based information, anyway. */
221 for (j = 0; j < 5; j++) {
222 switch (id.flaginfo[j].flagset){
223 case fa_unset: break;
224 case fa_isjmp: isjmp = 1; break;
225 case fa_isbranch: isjmp = 1; break;
226 case fa_zero: flagdead |= 1 << j; break;
227 case fa_one: flagdead |= 1 << j; break;
228 case fa_dontcare: flagdead |= 1 << j; break;
229 case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
230 case fa_set: flagdead |= 1 << j; break;
235 for (j = 0; j < 5; j++) {
236 switch (id.flaginfo[j].flaguse) {
237 case fu_unused: break;
238 case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
239 case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
240 case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
241 case fu_used: flaglive |= 1 << j; break;
246 for (variants = 0; variants < (1 << id.n_variable); variants++) {
251 uint16_t opc = id.bits;
258 wordsizes sz = sz_long;
259 int srcgather = 0, dstgather = 0;
260 int usesrc = 0, usedst = 0;
262 int srcpos = -1, dstpos = -1;
264 amodes srcmode = am_unknown, destmode = am_unknown;
265 int srcreg = -1, destreg = -1;
267 for (i = 0; i < lastbit; i++)
268 bitcnt[i] = bitval[i] = 0;
270 vmsk = 1 << id.n_variable;
272 for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) {
273 if (!(msk & id.mask)) {
274 int currbit = id.bitpos[bitno++];
277 bit_set = variants & vmsk ? 1 : 0;
280 bitpos[currbit] = 15 - i;
282 bitval[currbit] <<= 1;
283 bitval[currbit] |= bit_set;
287 if (bitval[bitj] == 0) bitval[bitj] = 8;
288 /* first check whether this one does not match after all */
289 if (bitval[bitz] == 3 || bitval[bitC] == 1)
291 if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
294 /* bitI and bitC get copied to biti and bitc */
296 bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
299 bitval[bitc] = bitval[bitC];
302 while (opcstr[pos] && !isspace((unsigned)opcstr[pos])) {
303 if (opcstr[pos] == '.') {
305 switch (opcstr[pos]) {
307 case 'B': sz = sz_byte; break;
308 case 'W': sz = sz_word; break;
309 case 'L': sz = sz_long; break;
311 switch (bitval[bitz]) {
312 case 0: sz = sz_byte; break;
313 case 1: sz = sz_word; break;
314 case 2: sz = sz_long; break;
321 mnemonic[mnp] = opcstr[pos];
322 if (mnemonic[mnp] == 'f') {
324 switch (bitval[bitf]) {
325 case 0: mnemonic[mnp] = 'R'; break;
326 case 1: mnemonic[mnp] = 'L'; break;
336 /* now, we have read the mnemonic and the size */
337 while (opcstr[pos] && isspace((unsigned)opcstr[pos]))
340 /* A goto a day keeps the D******a away. */
341 if (opcstr[pos] == 0)
344 /* parse the source address */
346 switch (opcstr[pos++]) {
349 switch (opcstr[pos++]) {
350 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
351 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
358 switch (opcstr[pos++]) {
359 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
360 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
363 switch (opcstr[pos]) {
364 case 'p': srcmode = Apdi; pos++; break;
365 case 'P': srcmode = Aipi; pos++; break;
372 switch (opcstr[pos++]) {
373 case 'z': srcmode = imm; break;
374 case '0': srcmode = imm0; break;
375 case '1': srcmode = imm1; break;
376 case '2': srcmode = imm2; break;
377 case 'i': srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
378 if (CPU_EMU_SIZE < 4) {
379 /* Used for branch instructions */
382 srcpos = bitpos[biti];
385 case 'j': srcmode = immi; srcreg = bitval[bitj];
386 if (CPU_EMU_SIZE < 3) {
387 /* 1..8 for ADDQ/SUBQ and rotshi insns */
390 srcpos = bitpos[bitj];
393 case 'J': srcmode = immi; srcreg = bitval[bitJ];
394 if (CPU_EMU_SIZE < 5) {
398 srcpos = bitpos[bitJ];
401 case 'k': srcmode = immi; srcreg = bitval[bitk];
402 if (CPU_EMU_SIZE < 3) {
405 srcpos = bitpos[bitk];
408 case 'K': srcmode = immi; srcreg = bitval[bitK];
409 if (CPU_EMU_SIZE < 5) {
413 srcpos = bitpos[bitK];
416 case 'p': srcmode = immi; srcreg = bitval[bitK];
417 if (CPU_EMU_SIZE < 5) {
421 srcpos = bitpos[bitp];
428 srcreg = bitval[bitD];
429 srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
430 if (srcmode == am_illg)
432 if (CPU_EMU_SIZE < 2 &&
433 (srcmode == Areg || srcmode == Dreg || srcmode == Aind
434 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
437 srcgather = 1; srcpos = bitpos[bitD];
439 if (opcstr[pos] == '[') {
441 if (opcstr[pos] == '!') {
445 if (mode_from_str(opcstr+pos) == srcmode)
448 } while (opcstr[pos] == ',');
451 if (opcstr[pos+4] == '-') {
453 if (mode_from_str(opcstr+pos) == srcmode)
454 srcmode = mode_from_str(opcstr+pos+5);
460 while(mode_from_str(opcstr+pos) != srcmode) {
462 if (opcstr[pos] == ']')
466 while(opcstr[pos] != ']') pos++;
472 /* Some addressing modes are invalid as destination */
473 if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
477 srcreg = bitval[bitS];
478 srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
480 if (srcmode == am_illg)
482 if (CPU_EMU_SIZE < 2 &&
483 (srcmode == Areg || srcmode == Dreg || srcmode == Aind
484 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
487 srcgather = 1; srcpos = bitpos[bitS];
489 if (opcstr[pos] == '[') {
491 if (opcstr[pos] == '!') {
495 if (mode_from_str(opcstr+pos) == srcmode)
498 } while (opcstr[pos] == ',');
501 if (opcstr[pos+4] == '-') {
503 if (mode_from_str(opcstr+pos) == srcmode)
504 srcmode = mode_from_str(opcstr+pos+5);
510 while(mode_from_str(opcstr+pos) != srcmode) {
512 if (opcstr[pos] == ']')
516 while(opcstr[pos] != ']') pos++;
524 /* safety check - might have changed */
525 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
526 && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
527 && srcmode != Apdi && srcmode != immi)
531 // if (srcmode == Areg && sz == sz_byte)
532 if (srcmode == Areg && sz == sz_byte && strcmp ( mnemonic , "MOVE" ) != 0 ) // [NP] move.b is valid on 68000
535 if (opcstr[pos] != ',')
539 /* parse the destination address */
541 switch (opcstr[pos++]) {
544 switch (opcstr[pos++]) {
545 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
546 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
549 if (dstpos < 0 || dstpos >= 32)
554 switch (opcstr[pos++]) {
555 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
556 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
557 case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
560 if (dstpos < 0 || dstpos >= 32)
562 switch (opcstr[pos]) {
563 case 'p': destmode = Apdi; pos++; break;
564 case 'P': destmode = Aipi; pos++; break;
571 switch (opcstr[pos++]) {
572 case 'z': destmode = imm; break;
573 case '0': destmode = imm0; break;
574 case '1': destmode = imm1; break;
575 case '2': destmode = imm2; break;
576 case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
577 case 'j': destmode = immi; destreg = bitval[bitj]; break;
578 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
579 case 'k': destmode = immi; destreg = bitval[bitk]; break;
580 case 'K': destmode = immi; destreg = bitval[bitK]; break;
585 destreg = bitval[bitD];
586 destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
587 if (destmode == am_illg)
589 if (CPU_EMU_SIZE < 1 &&
590 (destmode == Areg || destmode == Dreg || destmode == Aind
591 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
592 || destmode == Apdi))
594 dstgather = 1; dstpos = bitpos[bitD];
597 if (opcstr[pos] == '[') {
599 if (opcstr[pos] == '!') {
603 if (mode_from_str(opcstr+pos) == destmode)
606 } while (opcstr[pos] == ',');
609 if (opcstr[pos+4] == '-') {
611 if (mode_from_str(opcstr+pos) == destmode)
612 destmode = mode_from_str(opcstr+pos+5);
618 while(mode_from_str(opcstr+pos) != destmode) {
620 if (opcstr[pos] == ']')
624 while(opcstr[pos] != ']') pos++;
630 /* Some addressing modes are invalid as destination */
631 if (destmode == imm || destmode == PC16 || destmode == PC8r)
635 destreg = bitval[bitS];
636 destmode = mode_from_mr(bitval[bits],bitval[bitS]);
638 if (destmode == am_illg)
640 if (CPU_EMU_SIZE < 1 &&
641 (destmode == Areg || destmode == Dreg || destmode == Aind
642 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
643 || destmode == Apdi))
645 dstgather = 1; dstpos = bitpos[bitS];
648 if (opcstr[pos] == '[') {
650 if (opcstr[pos] == '!') {
654 if (mode_from_str(opcstr+pos) == destmode)
657 } while (opcstr[pos] == ',');
660 if (opcstr[pos+4] == '-') {
662 if (mode_from_str(opcstr+pos) == destmode)
663 destmode = mode_from_str(opcstr+pos+5);
669 while(mode_from_str(opcstr+pos) != destmode) {
671 if (opcstr[pos] == ']')
675 while(opcstr[pos] != ']') pos++;
683 /* safety check - might have changed */
684 if (destmode != Areg && destmode != Dreg && destmode != Aind
685 && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
691 if (destmode == Areg && sz == sz_byte)
694 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
699 /* now, we have a match */
700 if (table68k[opc].mnemo != i_ILLG)
701 fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
703 for (find = 0;; find++) {
704 if (strcmp(mnemonic, lookuptab[find].name) == 0) {
705 table68k[opc].mnemo = lookuptab[find].mnemo;
708 if (strlen(lookuptab[find].name) == 0) abort();
712 table68k[opc].mnemo = lookuptab[find].mnemo;
714 table68k[opc].cc = bitval[bitc];
715 if (table68k[opc].mnemo == i_BTST
716 || table68k[opc].mnemo == i_BSET
717 || table68k[opc].mnemo == i_BCLR
718 || table68k[opc].mnemo == i_BCHG)
720 sz = destmode == Dreg ? sz_long : sz_byte;
722 table68k[opc].size = sz;
723 table68k[opc].sreg = srcreg;
724 table68k[opc].dreg = destreg;
725 table68k[opc].smode = srcmode;
726 table68k[opc].dmode = destmode;
727 table68k[opc].spos = srcgather ? srcpos : -1;
728 table68k[opc].dpos = dstgather ? dstpos : -1;
729 table68k[opc].suse = usesrc;
730 table68k[opc].duse = usedst;
731 table68k[opc].stype = srctype;
732 table68k[opc].plev = id.plevel;
733 table68k[opc].clev = id.cpulevel;
735 for (i = 0; i < 5; i++) {
736 table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
737 table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
740 table68k[opc].flagdead = flagdead;
741 table68k[opc].flaglive = flaglive;
742 table68k[opc].isjmp = isjmp;
749 void read_table68k(void)
752 table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
754 for(i=0; i<65536; i++)
756 table68k[i].mnemo = i_ILLG;
757 table68k[i].handler = -1;
760 for(i=0; i<n_defs68k; i++)
766 static void handle_merges (long int opcode)
773 if (table68k[opcode].spos == -1)
780 switch (table68k[opcode].stype)
783 smsk = 7; sbitdst = 8; break;
785 smsk = 255; sbitdst = 256; break;
787 smsk = 15; sbitdst = 16; break;
789 smsk = 7; sbitdst = 8; break;
791 smsk = 7; sbitdst = 8; break;
793 smsk = 63; sbitdst = 64; break;
795 smsk = 3; sbitdst = 4; break;
797 smsk = 0; sbitdst = 0;
802 smsk <<= table68k[opcode].spos;
805 if (table68k[opcode].dpos == -1)
807 dstend = 1; dmsk = 0;
811 dmsk = 7 << table68k[opcode].dpos;
815 for(srcreg=0; srcreg<sbitdst; srcreg++)
817 for(dstreg=0; dstreg<dstend; dstreg++)
819 uint16_t code = opcode;
821 code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
822 code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
824 /* Check whether this is in fact the same instruction.
825 * The instructions should never differ, except for the
827 if (table68k[code].mnemo != table68k[opcode].mnemo
828 || table68k[code].size != table68k[opcode].size
829 || table68k[code].suse != table68k[opcode].suse
830 || table68k[code].duse != table68k[opcode].duse)
832 mismatch++; continue;
835 if (table68k[opcode].suse
836 && (table68k[opcode].spos != table68k[code].spos
837 || table68k[opcode].smode != table68k[code].smode
838 || table68k[opcode].stype != table68k[code].stype))
840 mismatch++; continue;
843 if (table68k[opcode].duse
844 && (table68k[opcode].dpos != table68k[code].dpos
845 || table68k[opcode].dmode != table68k[code].dmode))
847 mismatch++; continue;
852 table68k[code].handler = opcode;
853 //printf("Relocate... ($%04X->$%04X)\n", (uint16_t)opcode, code);
859 // What this really does is expand the # of handlers, which is why the
860 // opcode has to be passed into the opcode handler...
861 // E.g., $F620 maps into $F621-F627 as well; this code does this expansion.
868 for(opcode=0; opcode<65536; opcode++)
870 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
874 handle_merges(opcode);
880 int get_no_mismatches (void)