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;
177 STATIC_INLINE amodes mode_from_mr(int mode, int reg)
198 case 7: return am_illg;
206 static void build_insn(int insn)
215 int flaglive = 0, flagdead = 0;
218 /* Note: We treat anything with unknown flags as a jump. That
219 is overkill, but "the programmer" was lazy quite often, and
220 *this* programmer can't be bothered to work out what can and
221 can't trap. Usually, this will be overwritten with the gencomp
222 based information, anyway. */
226 switch (id.flaginfo[j].flagset)
228 case fa_unset: break;
229 case fa_isjmp: isjmp = 1; break;
230 case fa_isbranch: isjmp = 1; break;
231 case fa_zero: flagdead |= 1 << j; break;
232 case fa_one: flagdead |= 1 << j; break;
233 case fa_dontcare: flagdead |= 1 << j; break;
234 case fa_unknown: isjmp = 1; flagdead = -1; goto out1;
235 case fa_set: flagdead |= 1 << j; break;
242 switch (id.flaginfo[j].flaguse)
244 case fu_unused: break;
245 case fu_isjmp: isjmp = 1; flaglive |= 1 << j; break;
246 case fu_maybecc: isjmp = 1; flaglive |= 1 << j; break;
247 case fu_unknown: isjmp = 1; flaglive |= 1 << j; break;
248 case fu_used: flaglive |= 1 << j; break;
254 for(variants=0; variants<(1 << id.n_variable); variants++)
260 uint16_t opc = id.bits;
267 wordsizes sz = sz_long;
268 int srcgather = 0, dstgather = 0;
269 int usesrc = 0, usedst = 0;
271 int srcpos = -1, dstpos = -1;
273 amodes srcmode = am_unknown, destmode = am_unknown;
274 int srcreg = -1, destreg = -1;
276 for(i=0; i<lastbit; i++)
277 bitcnt[i] = bitval[i] = 0;
279 vmsk = 1 << id.n_variable;
281 for(i=0, msk=0x8000; i<16; i++, msk >>= 1)
283 if (!(msk & id.mask))
285 int currbit = id.bitpos[bitno++];
288 bit_set = (variants & vmsk ? 1 : 0);
293 bitpos[currbit] = 15 - i;
295 bitval[currbit] <<= 1;
296 bitval[currbit] |= bit_set;
300 if (bitval[bitj] == 0)
303 /* first check whether this one does not match after all */
304 if (bitval[bitz] == 3 || bitval[bitC] == 1)
307 if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff))
310 /* bitI and bitC get copied to biti and bitc */
313 bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI];
317 bitval[bitc] = bitval[bitC];
320 while (opcstr[pos] && !isspace((unsigned)opcstr[pos]))
322 if (opcstr[pos] == '.')
328 case 'B': sz = sz_byte; break;
329 case 'W': sz = sz_word; break;
330 case 'L': sz = sz_long; break;
332 switch (bitval[bitz])
334 case 0: sz = sz_byte; break;
335 case 1: sz = sz_word; break;
336 case 2: sz = sz_long; break;
345 mnemonic[mnp] = opcstr[pos];
347 if (mnemonic[mnp] == 'f')
350 switch (bitval[bitf])
352 case 0: mnemonic[mnp] = 'R'; break;
353 case 1: mnemonic[mnp] = 'L'; break;
366 /* now, we have read the mnemonic and the size */
367 while (opcstr[pos] && isspace((unsigned)opcstr[pos]))
370 /* A goto a day keeps the D******a away. */
371 if (opcstr[pos] == 0)
374 /* parse the source address */
376 switch (opcstr[pos++])
381 switch (opcstr[pos++])
383 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
384 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
392 switch (opcstr[pos++])
394 case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break;
395 case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break;
401 case 'p': srcmode = Apdi; pos++; break;
402 case 'P': srcmode = Aipi; pos++; break;
410 switch (opcstr[pos++])
412 case 'z': srcmode = imm; break;
413 case '0': srcmode = imm0; break;
414 case '1': srcmode = imm1; break;
415 case '2': srcmode = imm2; break;
417 srcmode = immi; srcreg = (int32_t)(int8_t)bitval[biti];
419 if (CPU_EMU_SIZE < 4)
421 /* Used for branch instructions */
424 srcpos = bitpos[biti];
429 srcmode = immi; srcreg = bitval[bitj];
431 if (CPU_EMU_SIZE < 3)
433 /* 1..8 for ADDQ/SUBQ and rotshi insns */
436 srcpos = bitpos[bitj];
441 srcmode = immi; srcreg = bitval[bitJ];
443 if (CPU_EMU_SIZE < 5)
448 srcpos = bitpos[bitJ];
453 srcmode = immi; srcreg = bitval[bitk];
455 if (CPU_EMU_SIZE < 3)
459 srcpos = bitpos[bitk];
464 srcmode = immi; srcreg = bitval[bitK];
466 if (CPU_EMU_SIZE < 5)
471 srcpos = bitpos[bitK];
476 srcmode = immi; srcreg = bitval[bitK];
478 if (CPU_EMU_SIZE < 5)
483 srcpos = bitpos[bitp];
492 srcreg = bitval[bitD];
493 srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
495 if (srcmode == am_illg)
499 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
500 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
504 srcpos = bitpos[bitD];
507 if (opcstr[pos] == '[')
511 if (opcstr[pos] == '!')
518 if (mode_from_str(opcstr + pos) == srcmode)
523 while (opcstr[pos] == ',');
529 if (opcstr[pos + 4] == '-')
532 if (mode_from_str(opcstr + pos) == srcmode)
533 srcmode = mode_from_str(opcstr + pos + 5);
542 while(mode_from_str(opcstr + pos) != srcmode)
546 if (opcstr[pos] == ']')
552 while(opcstr[pos] != ']')
561 /* Some addressing modes are invalid as destination */
562 if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
567 srcreg = bitval[bitS];
568 srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
570 if (srcmode == am_illg)
574 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind
575 || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
579 srcpos = bitpos[bitS];
582 if (opcstr[pos] == '[')
586 if (opcstr[pos] == '!')
593 if (mode_from_str(opcstr + pos) == srcmode)
598 while (opcstr[pos] == ',');
604 if (opcstr[pos + 4] == '-')
607 if (mode_from_str(opcstr + pos) == srcmode)
608 srcmode = mode_from_str(opcstr + pos + 5);
617 while(mode_from_str(opcstr+pos) != srcmode)
621 if (opcstr[pos] == ']')
627 while(opcstr[pos] != ']')
638 /* safety check - might have changed */
639 if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
640 && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
641 && srcmode != Apdi && srcmode != immi)
646 // if (srcmode == Areg && sz == sz_byte)
647 if (srcmode == Areg && sz == sz_byte && strcmp(mnemonic, "MOVE") != 0 ) // [NP] move.b is valid on 68000
650 if (opcstr[pos] != ',')
655 /* parse the destination address */
658 switch (opcstr[pos++])
663 switch (opcstr[pos++])
665 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
666 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
670 if (dstpos < 0 || dstpos >= 32)
677 switch (opcstr[pos++])
679 case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break;
680 case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break;
681 case 'x': destreg = 0; dstgather = 0; dstpos = 0; break;
685 if (dstpos < 0 || dstpos >= 32)
690 case 'p': destmode = Apdi; pos++; break;
691 case 'P': destmode = Aipi; pos++; break;
699 switch (opcstr[pos++])
701 case 'z': destmode = imm; break;
702 case '0': destmode = imm0; break;
703 case '1': destmode = imm1; break;
704 case '2': destmode = imm2; break;
705 case 'i': destmode = immi; destreg = (int32_t)(int8_t)bitval[biti]; break;
706 case 'j': destmode = immi; destreg = bitval[bitj]; break;
707 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
708 case 'k': destmode = immi; destreg = bitval[bitk]; break;
709 case 'K': destmode = immi; destreg = bitval[bitK]; break;
714 destreg = bitval[bitD];
715 destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
717 if (destmode == am_illg)
721 && (destmode == Areg || destmode == Dreg || destmode == Aind
722 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
723 || destmode == Apdi))
726 dstpos = bitpos[bitD];
729 if (opcstr[pos] == '[')
733 if (opcstr[pos] == '!')
740 if (mode_from_str(opcstr + pos) == destmode)
745 while (opcstr[pos] == ',');
751 if (opcstr[pos+4] == '-')
754 if (mode_from_str(opcstr + pos) == destmode)
755 destmode = mode_from_str(opcstr + pos + 5);
764 while(mode_from_str(opcstr + pos) != destmode)
768 if (opcstr[pos] == ']')
774 while(opcstr[pos] != ']')
783 /* Some addressing modes are invalid as destination */
784 if (destmode == imm || destmode == PC16 || destmode == PC8r)
789 destreg = bitval[bitS];
790 destmode = mode_from_mr(bitval[bits], bitval[bitS]);
792 if (destmode == am_illg)
795 && (destmode == Areg || destmode == Dreg || destmode == Aind
796 || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
797 || destmode == Apdi))
800 dstpos = bitpos[bitS];
803 if (opcstr[pos] == '[')
807 if (opcstr[pos] == '!')
814 if (mode_from_str(opcstr + pos) == destmode)
819 while (opcstr[pos] == ',');
825 if (opcstr[pos+4] == '-')
828 if (mode_from_str(opcstr + pos) == destmode)
829 destmode = mode_from_str(opcstr + pos + 5);
838 while (mode_from_str(opcstr + pos) != destmode)
842 if (opcstr[pos] == ']')
848 while (opcstr[pos] != ']')
859 /* safety check - might have changed */
860 if (destmode != Areg && destmode != Dreg && destmode != Aind
861 && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
867 if (destmode == Areg && sz == sz_byte)
870 if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
875 /* now, we have a match */
876 if (table68k[opc].mnemo != i_ILLG)
877 fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
881 for(find=0; ; find++)
883 if (strcmp(mnemonic, lookuptab[find].name) == 0)
885 table68k[opc].mnemo = lookuptab[find].mnemo;
889 if (strlen(lookuptab[find].name) == 0)
895 table68k[opc].mnemo = lookuptab[find].mnemo;
898 table68k[opc].cc = bitval[bitc];
900 if (table68k[opc].mnemo == i_BTST
901 || table68k[opc].mnemo == i_BSET
902 || table68k[opc].mnemo == i_BCLR
903 || table68k[opc].mnemo == i_BCHG)
905 sz = (destmode == Dreg ? sz_long : sz_byte);
908 table68k[opc].size = sz;
909 table68k[opc].sreg = srcreg;
910 table68k[opc].dreg = destreg;
911 table68k[opc].smode = srcmode;
912 table68k[opc].dmode = destmode;
913 table68k[opc].spos = (srcgather ? srcpos : -1);
914 table68k[opc].dpos = (dstgather ? dstpos : -1);
915 table68k[opc].suse = usesrc;
916 table68k[opc].duse = usedst;
917 table68k[opc].stype = srctype;
918 table68k[opc].plev = id.plevel;
919 table68k[opc].clev = id.cpulevel;
921 for (i = 0; i < 5; i++) {
922 table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset;
923 table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse;
926 table68k[opc].flagdead = flagdead;
927 table68k[opc].flaglive = flaglive;
928 table68k[opc].isjmp = isjmp;
936 void read_table68k(void)
939 table68k = (struct instr *)malloc(65536 * sizeof(struct instr));
941 for(i=0; i<65536; i++)
943 table68k[i].mnemo = i_ILLG;
944 table68k[i].handler = -1;
947 for(i=0; i<n_defs68k; i++)
953 static void handle_merges (long int opcode)
960 //0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W s,d[!Areg]
962 //0011 0001 1100 0011 : DDD = 0, ddd = 7, sss = 0, SSS = 3
964 if (table68k[opcode].spos == -1)
971 switch (table68k[opcode].stype)
974 smsk = 7; sbitdst = 8; break;
976 smsk = 255; sbitdst = 256; break;
978 smsk = 15; sbitdst = 16; break;
980 smsk = 7; sbitdst = 8; break;
982 smsk = 7; sbitdst = 8; break;
984 smsk = 63; sbitdst = 64; break;
986 smsk = 3; sbitdst = 4; break;
988 smsk = 0; sbitdst = 0;
993 smsk <<= table68k[opcode].spos;
996 if (table68k[opcode].dpos == -1)
1003 dmsk = 7 << table68k[opcode].dpos;
1007 for(srcreg=0; srcreg<sbitdst; srcreg++)
1009 for(dstreg=0; dstreg<dstend; dstreg++)
1011 uint16_t code = opcode;
1013 code = (code & ~smsk) | (srcreg << table68k[opcode].spos);
1014 code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos);
1016 /* Check whether this is in fact the same instruction.
1017 * The instructions should never differ, except for the
1019 if (table68k[code].mnemo != table68k[opcode].mnemo
1020 || table68k[code].size != table68k[opcode].size
1021 || table68k[code].suse != table68k[opcode].suse
1022 || table68k[code].duse != table68k[opcode].duse)
1028 if (table68k[opcode].suse
1029 && (table68k[opcode].spos != table68k[code].spos
1030 || table68k[opcode].smode != table68k[code].smode
1031 || table68k[opcode].stype != table68k[code].stype))
1037 if (table68k[opcode].duse
1038 && (table68k[opcode].dpos != table68k[code].dpos
1039 || table68k[opcode].dmode != table68k[code].dmode))
1047 table68k[code].handler = opcode;
1050 if (opcode == 0x31C3 || code == 0x31C3)
1052 printf("Relocate... ($%04X->$%04X)\n", (uint16_t)opcode, code);
1053 printf(" handler: %08X\n", table68k[code].handler);
1054 printf(" dreg: %i\n", table68k[code].dreg);
1055 printf(" sreg: %i\n", table68k[code].sreg);
1056 printf(" dpos: %i\n", table68k[code].dpos);
1057 printf(" spos: %i\n", table68k[code].spos);
1058 printf(" sduse: %i\n", table68k[code].sduse);
1059 printf("flagdead: %i\n", table68k[code].flagdead);
1060 printf("flaglive: %i\n", table68k[code].flaglive);
1069 unsigned char sduse;
1070 int flagdead:8, flaglive:8;
1071 unsigned int mnemo:8;
1073 unsigned int plev:2;
1074 unsigned int size:2;
1075 unsigned int smode:5;
1076 unsigned int stype:3;
1077 unsigned int dmode:5;
1078 unsigned int suse:1;
1079 unsigned int duse:1;
1080 unsigned int unused1:1;
1081 unsigned int clev:3;
1082 unsigned int isjmp:1;
1083 unsigned int unused2:4;
1090 // What this really does is expand the # of handlers, which is why the
1091 // opcode has to be passed into the opcode handler...
1092 // E.g., $F620 maps into $F621-F627 as well; this code does this expansion.
1093 void do_merges(void)
1099 for(opcode=0; opcode<65536; opcode++)
1101 if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG)
1105 handle_merges(opcode);
1108 nr_cpuop_funcs = nr;
1111 int get_no_mismatches(void)