--- uae/src/readcpu.c 2018/04/24 16:38:39 1.1.1.1 +++ uae/src/readcpu.c 2018/04/24 16:39:49 1.1.1.2 @@ -1,4 +1,4 @@ -/* +/* * UAE - The Un*x Amiga Emulator * * Read 68000 CPU specs from file "table68k" @@ -14,73 +14,75 @@ #include "options.h" #include "readcpu.h" +int nr_cpuop_funcs; + struct mnemolookup lookuptab[] = { { i_ILLG, "ILLEGAL" }, { i_OR, "OR" }, { i_CHK, "CHK" }, { i_CHK2, "CHK2" }, - { i_AND, "AND" }, + { i_AND, "AND" }, { i_EOR, "EOR" }, - { i_ORSR, "ORSR" }, - { i_ANDSR, "ANDSR" }, - { i_EORSR, "EORSR" }, - { i_SUB, "SUB" }, - { i_SUBA, "SUBA" }, - { i_SUBX, "SUBX" }, - { i_SBCD, "SBCD" }, - { i_ADD, "ADD" }, - { i_ADDA, "ADDA" }, - { i_ADDX, "ADDX" }, + { i_ORSR, "ORSR" }, + { i_ANDSR, "ANDSR" }, + { i_EORSR, "EORSR" }, + { i_SUB, "SUB" }, + { i_SUBA, "SUBA" }, + { i_SUBX, "SUBX" }, + { i_SBCD, "SBCD" }, + { i_ADD, "ADD" }, + { i_ADDA, "ADDA" }, + { i_ADDX, "ADDX" }, { i_ABCD, "ABCD" }, - { i_NEG, "NEG" }, - { i_NEGX, "NEGX" }, - { i_NBCD, "NBCD" }, - { i_CLR, "CLR" }, - { i_NOT, "NOT" }, - { i_TST, "TST" }, - { i_BTST, "BTST" }, - { i_BCHG, "BCHG" }, - { i_BCLR, "BCLR" }, + { i_NEG, "NEG" }, + { i_NEGX, "NEGX" }, + { i_NBCD, "NBCD" }, + { i_CLR, "CLR" }, + { i_NOT, "NOT" }, + { i_TST, "TST" }, + { i_BTST, "BTST" }, + { i_BCHG, "BCHG" }, + { i_BCLR, "BCLR" }, { i_BSET, "BSET" }, - { i_CMP, "CMP" }, - { i_CMPM, "CMPM" }, - { i_CMPA, "CMPA" }, + { i_CMP, "CMP" }, + { i_CMPM, "CMPM" }, + { i_CMPA, "CMPA" }, { i_MVPRM, "MVPRM" }, { i_MVPMR, "MVPMR" }, - { i_MOVE, "MOVE" }, + { i_MOVE, "MOVE" }, { i_MOVEA, "MOVEA" }, { i_MVSR2, "MVSR2" }, - { i_MV2SR, "MV2SR" }, + { i_MV2SR, "MV2SR" }, { i_SWAP, "SWAP" }, { i_EXG, "EXG" }, { i_EXT, "EXT" }, - { i_MVMEL, "MVMEL" }, - { i_MVMLE, "MVMLE" }, + { i_MVMEL, "MVMEL" }, + { i_MVMLE, "MVMLE" }, { i_TRAP, "TRAP" }, - { i_MVR2USP, "MVR2USP" }, - { i_MVUSP2R, "MVUSP2R" }, + { i_MVR2USP, "MVR2USP" }, + { i_MVUSP2R, "MVUSP2R" }, { i_NOP, "NOP" }, { i_RESET, "RESET" }, { i_RTE, "RTE" }, - { i_RTD, "RTD" }, + { i_RTD, "RTD" }, { i_LINK, "LINK" }, - { i_UNLK, "UNLK" }, - { i_RTS, "RTS" }, + { i_UNLK, "UNLK" }, + { i_RTS, "RTS" }, { i_STOP, "STOP" }, - { i_TRAPV, "TRAPV" }, - { i_RTR, "RTR" }, + { i_TRAPV, "TRAPV" }, + { i_RTR, "RTR" }, { i_JSR, "JSR" }, { i_JMP, "JMP" }, { i_BSR, "BSR" }, { i_Bcc, "Bcc" }, { i_LEA, "LEA" }, { i_PEA, "PEA" }, - { i_DBcc, "DBcc" }, - { i_Scc, "Scc" }, - { i_DIVU, "DIVU" }, + { i_DBcc, "DBcc" }, + { i_Scc, "Scc" }, + { i_DIVU, "DIVU" }, { i_DIVS, "DIVS" }, { i_MULU, "MULU" }, - { i_MULS, "MULS" }, + { i_MULS, "MULS" }, { i_ASR, "ASR" }, { i_ASL, "ASL" }, { i_LSR, "LSR" }, @@ -97,7 +99,7 @@ struct mnemolookup lookuptab[] = { { i_RORW, "RORW" }, { i_ROXLW, "ROXLW" }, { i_ROXRW, "ROXRW" }, - + { i_MOVE2C, "MOVE2C" }, { i_MOVEC2, "MOVEC2" }, { i_CAS, "CAS" }, @@ -152,17 +154,17 @@ static __inline__ amodes mode_from_str(c return(0); } -static __inline__ amodes mode_from_mr(int mode, int reg) +static __inline__ amodes mode_from_mr(int mode, int reg) { switch(mode) { - case 0: return Dreg; + case 0: return Dreg; case 1: return Areg; case 2: return Aind; case 3: return Aipi; case 4: return Apdi; case 5: return Ad16; case 6: return Ad8r; - case 7: + case 7: switch(reg) { case 0: return absw; case 1: return absl; @@ -189,7 +191,7 @@ static void build_insn(int insn) int flaglive = 0, flagdead = 0; id = defs68k[insn]; - + for(i = 0; i < 5; i++) { switch(id.flaginfo[i].flagset){ case fa_unset: break; @@ -213,35 +215,35 @@ static void build_insn(int insn) } } out2: - + opcstr = id.opcstr; for (variants = 0; variants < (1 << id.n_variable); variants++) { int bitcnt[lastbit]; int bitval[lastbit]; int bitpos[lastbit]; int i; - UWORD opc = id.bits; - UWORD msk, vmsk; + uae_u16 opc = id.bits; + uae_u16 msk, vmsk; int pos = 0; int mnp = 0; int bitno = 0; char mnemonic[10]; - + wordsizes sz = sz_long; int srcgather = 0, dstgather = 0; int usesrc = 0, usedst = 0; int srctype = 0; int srcpos = -1, dstpos = -1; - + amodes srcmode = am_unknown, destmode = am_unknown; int srcreg = -1, destreg = -1; - - for(i = 0; i < lastbit; i++) + + for(i = 0; i < lastbit; i++) bitcnt[i] = bitval[i] = 0; vmsk = 1 << id.n_variable; - - for(i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { + + for(i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { if (!(msk & id.mask)) { int currbit = id.bitpos[bitno++]; int bit_set; @@ -255,31 +257,31 @@ static void build_insn(int insn) bitval[currbit] |= bit_set; } } - + if (bitval[bitj] == 0) bitval[bitj] = 8; /* first check whether this one does not match after all */ if (bitval[bitz] == 3 || bitval[bitC] == 1) - continue; - if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) + continue; + if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) continue; /* bitI and bitC get copied to biti and bitc */ if (bitcnt[bitI]) { - bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; + bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; } - if (bitcnt[bitC]) + if (bitcnt[bitC]) bitval[bitc] = bitval[bitC]; - + pos = 0; while (opcstr[pos] && !isspace(opcstr[pos])) { if (opcstr[pos] == '.') { pos++; switch(opcstr[pos]) { - + case 'B': sz = sz_byte; break; case 'W': sz = sz_word; break; case 'L': sz = sz_long; break; - case 'z': + case 'z': switch(bitval[bitz]) { case 0: sz = sz_byte; break; case 1: sz = sz_word; break; @@ -289,7 +291,7 @@ static void build_insn(int insn) break; default: abort(); } - } else { + } else { mnemonic[mnp] = opcstr[pos]; if(mnemonic[mnp] == 'f') { find = -1; @@ -301,31 +303,31 @@ static void build_insn(int insn) } mnp++; } - pos++; + pos++; } mnemonic[mnp] = 0; - + /* now, we have read the mnemonic and the size */ - while (opcstr[pos] && isspace(opcstr[pos])) + while (opcstr[pos] && isspace(opcstr[pos])) pos++; - + /* A goto a day keeps the D******a away. */ if (opcstr[pos] == 0) goto endofline; - + /* parse the source address */ usesrc = 1; switch(opcstr[pos++]) { - case 'D': + case 'D': srcmode = Dreg; switch (opcstr[pos++]) { case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; default: abort(); } - + break; - case 'A': + case 'A': srcmode = Areg; switch (opcstr[pos++]) { case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; @@ -343,11 +345,11 @@ static void build_insn(int insn) case '0': srcmode = imm0; break; case '1': srcmode = imm1; break; case '2': srcmode = imm2; break; - case 'i': srcmode = immi; srcreg = (LONG)(BYTE)bitval[biti]; + case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; if (CPU_EMU_SIZE < 4) { /* Used for branch instructions */ srctype = 1; - srcgather = 1; + srcgather = 1; srcpos = bitpos[biti]; } break; @@ -389,8 +391,8 @@ static void build_insn(int insn) srcreg = bitval[bitD]; srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); if (srcmode == am_illg) continue; - if (CPU_EMU_SIZE < 2 && - (srcmode == Areg || srcmode == Dreg || srcmode == Aind + if (CPU_EMU_SIZE < 2 && + (srcmode == Areg || srcmode == Dreg || srcmode == Aind || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi || srcmode == Apdi)) { @@ -400,17 +402,17 @@ static void build_insn(int insn) pos++; if (opcstr[pos] == '!') { /* exclusion */ - do { + do { pos++; - if (mode_from_str(opcstr+pos) == srcmode) + if (mode_from_str(opcstr+pos) == srcmode) goto nomatch; - pos += 4; + pos += 4; } while (opcstr[pos] == ','); pos++; } else { if (opcstr[pos+4] == '-') { /* replacement */ - if (mode_from_str(opcstr+pos) == srcmode) + if (mode_from_str(opcstr+pos) == srcmode) srcmode = mode_from_str(opcstr+pos+5); else goto nomatch; @@ -431,15 +433,15 @@ static void build_insn(int insn) } /* Some addressing modes are invalid as destination */ if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) - goto nomatch; + goto nomatch; break; case 's': srcreg = bitval[bitS]; srcmode = mode_from_mr(bitval[bits],bitval[bitS]); - - if (srcmode == am_illg) continue; - if (CPU_EMU_SIZE < 2 && - (srcmode == Areg || srcmode == Dreg || srcmode == Aind + + if (srcmode == am_illg) continue; + if (CPU_EMU_SIZE < 2 && + (srcmode == Areg || srcmode == Dreg || srcmode == Aind || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi || srcmode == Apdi)) { @@ -449,17 +451,17 @@ static void build_insn(int insn) pos++; if (opcstr[pos] == '!') { /* exclusion */ - do { + do { pos++; - if (mode_from_str(opcstr+pos) == srcmode) + if (mode_from_str(opcstr+pos) == srcmode) goto nomatch; - pos += 4; + pos += 4; } while (opcstr[pos] == ','); pos++; } else { if (opcstr[pos+4] == '-') { /* replacement */ - if (mode_from_str(opcstr+pos) == srcmode) + if (mode_from_str(opcstr+pos) == srcmode) srcmode = mode_from_str(opcstr+pos+5); else goto nomatch; @@ -468,7 +470,7 @@ static void build_insn(int insn) /* normal */ while(mode_from_str(opcstr+pos) != srcmode) { pos += 4; - if (opcstr[pos] == ']') + if (opcstr[pos] == ']') goto nomatch; pos++; } @@ -481,7 +483,7 @@ static void build_insn(int insn) default: abort(); } /* safety check - might have changed */ - if (srcmode != Areg && srcmode != Dreg && srcmode != Aind + if (srcmode != Areg && srcmode != Dreg && srcmode != Aind && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi && srcmode != Apdi && srcmode != immi) { @@ -489,15 +491,15 @@ static void build_insn(int insn) } if (srcmode == Areg && sz == sz_byte) goto nomatch; - + if (opcstr[pos] != ',') goto endofline; pos++; - + /* parse the destination address */ - usedst = 1; + usedst = 1; switch(opcstr[pos++]) { - case 'D': + case 'D': destmode = Dreg; switch (opcstr[pos++]) { case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; @@ -505,7 +507,7 @@ static void build_insn(int insn) default: abort(); } break; - case 'A': + case 'A': destmode = Areg; switch (opcstr[pos++]) { case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; @@ -523,7 +525,7 @@ static void build_insn(int insn) case '0': destmode = imm0; break; case '1': destmode = imm1; break; case '2': destmode = imm2; break; - case 'i': destmode = immi; destreg = (LONG)(BYTE)bitval[biti]; break; + case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; case 'j': destmode = immi; destreg = bitval[bitj]; break; case 'J': destmode = immi; destreg = bitval[bitJ]; break; case 'k': destmode = immi; destreg = bitval[bitk]; break; @@ -535,29 +537,29 @@ static void build_insn(int insn) destreg = bitval[bitD]; destmode = mode_from_mr(bitval[bitd],bitval[bitD]); if(destmode == am_illg) continue; - if (CPU_EMU_SIZE < 1 && - (destmode == Areg || destmode == Dreg || destmode == Aind + if (CPU_EMU_SIZE < 1 && + (destmode == Areg || destmode == Dreg || destmode == Aind || destmode == Ad16 || destmode == Ad8r || destmode == Aipi || destmode == Apdi)) { dstgather = 1; dstpos = bitpos[bitD]; } - + if (opcstr[pos] == '[') { pos++; if (opcstr[pos] == '!') { /* exclusion */ - do { + do { pos++; - if (mode_from_str(opcstr+pos) == destmode) + if (mode_from_str(opcstr+pos) == destmode) goto nomatch; - pos += 4; + pos += 4; } while (opcstr[pos] == ','); pos++; } else { if (opcstr[pos+4] == '-') { /* replacement */ - if (mode_from_str(opcstr+pos) == destmode) + if (mode_from_str(opcstr+pos) == destmode) destmode = mode_from_str(opcstr+pos+5); else goto nomatch; @@ -583,31 +585,31 @@ static void build_insn(int insn) case 's': destreg = bitval[bitS]; destmode = mode_from_mr(bitval[bits],bitval[bitS]); - - if (destmode == am_illg) continue; - if (CPU_EMU_SIZE < 1 && - (destmode == Areg || destmode == Dreg || destmode == Aind + + if (destmode == am_illg) continue; + if (CPU_EMU_SIZE < 1 && + (destmode == Areg || destmode == Dreg || destmode == Aind || destmode == Ad16 || destmode == Ad8r || destmode == Aipi || destmode == Apdi)) { dstgather = 1; dstpos = bitpos[bitS]; } - + if (opcstr[pos] == '[') { pos++; if (opcstr[pos] == '!') { /* exclusion */ - do { + do { pos++; if (mode_from_str(opcstr+pos) == destmode) goto nomatch; - pos += 4; + pos += 4; } while (opcstr[pos] == ','); pos++; } else { if (opcstr[pos+4] == '-') { /* replacement */ - if (mode_from_str(opcstr+pos) == destmode) + if (mode_from_str(opcstr+pos) == destmode) destmode = mode_from_str(opcstr+pos+5); else goto nomatch; @@ -629,13 +631,13 @@ static void build_insn(int insn) default: abort(); } /* safety check - might have changed */ - if (destmode != Areg && destmode != Dreg && destmode != Aind + if (destmode != Areg && destmode != Dreg && destmode != Aind && destmode != Ad16 && destmode != Ad8r && destmode != Aipi && destmode != Apdi) { dstgather = 0; } - + if (destmode == Areg && sz == sz_byte) goto nomatch; #if 0 @@ -649,11 +651,11 @@ static void build_insn(int insn) fprintf(stderr, "Double match: %x: %s\n", opc, opcstr); if (find == -1) { for(find = 0;; find++) { - if (strcmp(mnemonic, lookuptab[find].name) == 0) { + if (strcmp(mnemonic, lookuptab[find].name) == 0) { table68k[opc].mnemo = lookuptab[find].mnemo; break; - } - if (strlen(lookuptab[find].name) == 0) abort(); + } + if (strlen(lookuptab[find].name) == 0) abort(); } } else { @@ -663,7 +665,7 @@ static void build_insn(int insn) if (table68k[opc].mnemo == i_BTST || table68k[opc].mnemo == i_BSET || table68k[opc].mnemo == i_BCLR - || table68k[opc].mnemo == i_BCHG) + || table68k[opc].mnemo == i_BCHG) { sz = destmode == Dreg ? sz_long : sz_byte; } @@ -678,6 +680,7 @@ static void build_insn(int insn) table68k[opc].duse = usedst; table68k[opc].stype = srctype; table68k[opc].plev = id.plevel; + table68k[opc].clev = id.cpulevel; #if 0 for (i = 0; i < 5; i++) { table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; @@ -696,7 +699,7 @@ void read_table68k () { int i; - table68k = (struct instr *)malloc (65536 * sizeof (struct instr)); + table68k = (struct instr *)xmalloc (65536 * sizeof (struct instr)); for(i = 0; i < 65536; i++) { table68k[i].mnemo = i_ILLG; table68k[i].handler = -1; @@ -710,73 +713,71 @@ static int mismatch; static void handle_merges(long int opcode) { - UWORD smsk; - UWORD dmsk; + uae_u16 smsk; + uae_u16 dmsk; int sbitdst, dstend; int srcreg, dstreg; - + if (table68k[opcode].spos == -1) { sbitdst = 1; smsk = 0; - } - else { - switch (table68k[opcode].stype) { - case 0: + } else { + switch (table68k[opcode].stype) { + case 0: smsk = 7; sbitdst = 8; break; - case 1: + case 1: smsk = 255; sbitdst = 256; break; - case 2: + case 2: smsk = 15; sbitdst = 16; break; - case 3: + case 3: smsk = 7; sbitdst = 8; break; - case 4: + case 4: smsk = 7; sbitdst = 8; break; - case 5: + case 5: smsk = 63; sbitdst = 64; break; - default: + default: smsk = 0; sbitdst = 0; abort(); break; - } - smsk <<= table68k[opcode].spos; + } + smsk <<= table68k[opcode].spos; } if (table68k[opcode].dpos == -1) { dstend = 1; dmsk = 0; - } - else { - dmsk = 7 << table68k[opcode].dpos; + } else { + dmsk = 7 << table68k[opcode].dpos; dstend = 8; } for (srcreg=0; srcreg < sbitdst; srcreg++) { for (dstreg=0; dstreg < dstend; dstreg++) { - UWORD code = opcode; + uae_u16 code = opcode; code = (code & ~smsk) | (srcreg << table68k[opcode].spos); - code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); - + code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); + /* Check whether this is in fact the same instruction. * The instructions should never differ, except for the * Bcc.(BW) case. */ if (table68k[code].mnemo != table68k[opcode].mnemo || table68k[code].size != table68k[opcode].size || table68k[code].suse != table68k[opcode].suse - || table68k[code].duse != table68k[opcode].duse) + || table68k[code].duse != table68k[opcode].duse) { mismatch++; continue; } - if (table68k[opcode].suse + if (table68k[opcode].suse && (table68k[opcode].spos != table68k[code].spos || table68k[opcode].smode != table68k[code].smode || table68k[opcode].stype != table68k[code].stype)) { mismatch++; continue; } - if (table68k[opcode].duse + if (table68k[opcode].duse && (table68k[opcode].dpos != table68k[code].dpos || table68k[opcode].dmode != table68k[code].dmode)) { mismatch++; continue; } - + if (code != opcode) table68k[code].handler = opcode; } @@ -786,14 +787,15 @@ static void handle_merges(long int opcod void do_merges () { long int opcode; + int nr = 0; mismatch = 0; - for (opcode = 0; opcode < 65536; opcode++) { if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) continue; + nr++; handle_merges (opcode); } - + nr_cpuop_funcs = nr; } int get_no_mismatches ()