--- uae/src/readcpu.c 2018/04/24 16:39:49 1.1.1.2 +++ uae/src/readcpu.c 2018/04/24 16:59:56 1.1.1.6 @@ -130,33 +130,42 @@ struct mnemolookup lookuptab[] = { { i_FBcc, "FBcc" }, { i_FSAVE, "FSAVE" }, { i_FRESTORE, "FRESTORE" }, + + { i_CINVL, "CINVL" }, + { i_CINVP, "CINVP" }, + { i_CINVA, "CINVA" }, + { i_CPUSHL, "CPUSHL" }, + { i_CPUSHP, "CPUSHP" }, + { i_CPUSHA, "CPUSHA" }, + { i_MOVE16, "MOVE16" }, + { i_MMUOP, "MMUOP" }, { i_ILLG, "" }, }; struct instr *table68k; -static __inline__ amodes mode_from_str(const char *str) +STATIC_INLINE amodes mode_from_str (const char *str) { - if (strncmp(str,"Dreg",4) == 0) return Dreg; - if (strncmp(str,"Areg",4) == 0) return Areg; - if (strncmp(str,"Aind",4) == 0) return Aind; - if (strncmp(str,"Apdi",4) == 0) return Apdi; - if (strncmp(str,"Aipi",4) == 0) return Aipi; - if (strncmp(str,"Ad16",4) == 0) return Ad16; - if (strncmp(str,"Ad8r",4) == 0) return Ad8r; - if (strncmp(str,"absw",4) == 0) return absw; - if (strncmp(str,"absl",4) == 0) return absl; - if (strncmp(str,"PC16",4) == 0) return PC16; - if (strncmp(str,"PC8r",4) == 0) return PC8r; - if (strncmp(str,"Immd",4) == 0) return imm; - abort(); - return(0); + if (strncmp (str, "Dreg", 4) == 0) return Dreg; + if (strncmp (str, "Areg", 4) == 0) return Areg; + if (strncmp (str, "Aind", 4) == 0) return Aind; + if (strncmp (str, "Apdi", 4) == 0) return Apdi; + if (strncmp (str, "Aipi", 4) == 0) return Aipi; + if (strncmp (str, "Ad16", 4) == 0) return Ad16; + if (strncmp (str, "Ad8r", 4) == 0) return Ad8r; + if (strncmp (str, "absw", 4) == 0) return absw; + if (strncmp (str, "absl", 4) == 0) return absl; + if (strncmp (str, "PC16", 4) == 0) return PC16; + if (strncmp (str, "PC8r", 4) == 0) return PC8r; + if (strncmp (str, "Immd", 4) == 0) return imm; + abort (); + return 0; } -static __inline__ amodes mode_from_mr(int mode, int reg) +STATIC_INLINE amodes mode_from_mr (int mode, int reg) { - switch(mode) { + switch (mode) { case 0: return Dreg; case 1: return Areg; case 2: return Aind; @@ -165,7 +174,7 @@ static __inline__ amodes mode_from_mr(in case 5: return Ad16; case 6: return Ad8r; case 7: - switch(reg) { + switch (reg) { case 0: return absw; case 1: return absl; case 2: return PC16; @@ -176,14 +185,15 @@ static __inline__ amodes mode_from_mr(in case 7: return am_illg; } } - abort(); - return(0); + abort (); + return 0; } -static void build_insn(int insn) +static void build_insn (int insn) { int find = -1; int variants; + int isjmp = 0; struct instr_def id; const char *opcstr; int i; @@ -192,29 +202,36 @@ static void build_insn(int insn) id = defs68k[insn]; - for(i = 0; i < 5; i++) { - switch(id.flaginfo[i].flagset){ - case fa_unset: break; - case fa_isjmp: break; - case fa_zero: flagdead |= 1 << i; break; - case fa_one: flagdead |= 1 << i; break; - case fa_dontcare: flagdead |= 1 << i; break; - case fa_unknown: flagdead = -1; goto out1; - case fa_set: flagdead |= 1 << i; break; + /* Note: We treat anything with unknown flags as a jump. That + is overkill, but "the programmer" was lazy quite often, and + *this* programmer can't be bothered to work out what can and + can't trap. Usually, this will be overwritten with the gencomp + based information, anyway. */ + + for (i = 0; i < 5; i++) { + switch (id.flaginfo[i].flagset){ + case fa_unset: break; + case fa_isjmp: isjmp = 1; break; + case fa_isbranch: isjmp = 1; break; + case fa_zero: flagdead |= 1 << i; break; + case fa_one: flagdead |= 1 << i; break; + case fa_dontcare: flagdead |= 1 << i; break; + case fa_unknown: isjmp = 1; flagdead = -1; goto out1; + case fa_set: flagdead |= 1 << i; break; } } - out1: - for(i = 0; i < 5; i++) { - switch(id.flaginfo[i].flaguse) { - case fu_unused: break; - case fu_isjmp: flaglive |= 1 << i; break; - case fu_maybecc: flaglive |= 1 << i; break; - case fu_unknown: flaglive = -1; goto out2; - case fu_used: flaglive |= 1 << i; break; + out1: + for (i = 0; i < 5; i++) { + switch (id.flaginfo[i].flaguse) { + case fu_unused: break; + case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; + case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; + case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; + case fu_used: flaglive |= 1 << i; break; } } - out2: + out2: opcstr = id.opcstr; for (variants = 0; variants < (1 << id.n_variable); variants++) { @@ -238,12 +255,12 @@ static void build_insn(int insn) 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; @@ -276,29 +293,29 @@ static void build_insn(int insn) while (opcstr[pos] && !isspace(opcstr[pos])) { if (opcstr[pos] == '.') { pos++; - switch(opcstr[pos]) { + switch (opcstr[pos]) { - case 'B': sz = sz_byte; break; - case 'W': sz = sz_word; break; - case 'L': sz = sz_long; break; - case 'z': - switch(bitval[bitz]) { - case 0: sz = sz_byte; break; - case 1: sz = sz_word; break; - case 2: sz = sz_long; break; - default: abort(); + case 'B': sz = sz_byte; break; + case 'W': sz = sz_word; break; + case 'L': sz = sz_long; break; + case 'z': + switch (bitval[bitz]) { + case 0: sz = sz_byte; break; + case 1: sz = sz_word; break; + case 2: sz = sz_long; break; + default: abort(); } break; - default: abort(); + default: abort(); } } else { mnemonic[mnp] = opcstr[pos]; - if(mnemonic[mnp] == 'f') { + if (mnemonic[mnp] == 'f') { find = -1; - switch(bitval[bitf]) { - case 0: mnemonic[mnp] = 'R'; break; - case 1: mnemonic[mnp] = 'L'; break; - default: abort(); + switch (bitval[bitf]) { + case 0: mnemonic[mnp] = 'R'; break; + case 1: mnemonic[mnp] = 'L'; break; + default: abort(); } } mnp++; @@ -317,35 +334,37 @@ static void build_insn(int insn) /* parse the source address */ usesrc = 1; - switch(opcstr[pos++]) { - case 'D': + switch (opcstr[pos++]) { + 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(); + 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; - case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; - default: abort(); + case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; + case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; + default: abort(); } switch (opcstr[pos]) { - case 'p': srcmode = Apdi; pos++; break; - case 'P': srcmode = Aipi; pos++; break; + case 'p': srcmode = Apdi; pos++; break; + case 'P': srcmode = Aipi; pos++; break; } break; - case '#': - switch(opcstr[pos++]) { - case 'z': srcmode = imm; break; - case '0': srcmode = imm0; break; - case '1': srcmode = imm1; break; - case '2': srcmode = imm2; break; - case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; + case 'L': + srcmode = absl; + break; + case '#': + switch (opcstr[pos++]) { + case 'z': srcmode = imm; break; + case '0': srcmode = imm0; break; + case '1': srcmode = imm1; break; + case '2': srcmode = imm2; break; + case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; if (CPU_EMU_SIZE < 4) { /* Used for branch instructions */ srctype = 1; @@ -353,7 +372,7 @@ static void build_insn(int insn) srcpos = bitpos[biti]; } break; - case 'j': srcmode = immi; srcreg = bitval[bitj]; + case 'j': srcmode = immi; srcreg = bitval[bitj]; if (CPU_EMU_SIZE < 3) { /* 1..8 for ADDQ/SUBQ and rotshi insns */ srcgather = 1; @@ -361,7 +380,7 @@ static void build_insn(int insn) srcpos = bitpos[bitj]; } break; - case 'J': srcmode = immi; srcreg = bitval[bitJ]; + case 'J': srcmode = immi; srcreg = bitval[bitJ]; if (CPU_EMU_SIZE < 5) { /* 0..15 */ srcgather = 1; @@ -369,14 +388,14 @@ static void build_insn(int insn) srcpos = bitpos[bitJ]; } break; - case 'k': srcmode = immi; srcreg = bitval[bitk]; + case 'k': srcmode = immi; srcreg = bitval[bitk]; if (CPU_EMU_SIZE < 3) { srcgather = 1; srctype = 4; srcpos = bitpos[bitk]; } break; - case 'K': srcmode = immi; srcreg = bitval[bitK]; + case 'K': srcmode = immi; srcreg = bitval[bitK]; if (CPU_EMU_SIZE < 5) { /* 0..15 */ srcgather = 1; @@ -384,20 +403,29 @@ static void build_insn(int insn) srcpos = bitpos[bitK]; } break; - default: abort(); + case 'p': srcmode = immi; srcreg = bitval[bitK]; + if (CPU_EMU_SIZE < 5) { + /* 0..3 */ + srcgather = 1; + srctype = 7; + srcpos = bitpos[bitp]; + } + break; + default: abort(); } break; - case 'd': + case 'd': srcreg = bitval[bitD]; srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); - if (srcmode == am_illg) continue; + if (srcmode == am_illg) + continue; if (CPU_EMU_SIZE < 2 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi || srcmode == Apdi)) - { - srcgather = 1; srcpos = bitpos[bitD]; - } + { + srcgather = 1; srcpos = bitpos[bitD]; + } if (opcstr[pos] == '[') { pos++; if (opcstr[pos] == '!') { @@ -435,18 +463,19 @@ static void build_insn(int insn) if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) goto nomatch; break; - case 's': + case 's': srcreg = bitval[bitS]; srcmode = mode_from_mr(bitval[bits],bitval[bitS]); - if (srcmode == am_illg) continue; + if (srcmode == am_illg) + continue; if (CPU_EMU_SIZE < 2 && (srcmode == Areg || srcmode == Dreg || srcmode == Aind || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi || srcmode == Apdi)) - { - srcgather = 1; srcpos = bitpos[bitS]; - } + { + srcgather = 1; srcpos = bitpos[bitS]; + } if (opcstr[pos] == '[') { pos++; if (opcstr[pos] == '!') { @@ -480,15 +509,15 @@ static void build_insn(int insn) } } break; - default: abort(); + default: abort(); } /* safety check - might have changed */ if (srcmode != Areg && srcmode != Dreg && srcmode != Aind && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi && srcmode != Apdi && srcmode != immi) - { - srcgather = 0; - } + { + srcgather = 0; + } if (srcmode == Areg && sz == sz_byte) goto nomatch; @@ -498,52 +527,61 @@ static void build_insn(int insn) /* parse the destination address */ usedst = 1; - switch(opcstr[pos++]) { - case 'D': + switch (opcstr[pos++]) { + case 'D': destmode = Dreg; switch (opcstr[pos++]) { - case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; - case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; - default: abort(); + case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; + case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + default: abort(); } + if (dstpos < 0 || dstpos >= 32) + abort (); break; - case 'A': + case 'A': destmode = Areg; switch (opcstr[pos++]) { - case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; - case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; - default: abort(); + case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; + case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; + case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; + default: abort(); } + if (dstpos < 0 || dstpos >= 32) + abort (); switch (opcstr[pos]) { - case 'p': destmode = Apdi; pos++; break; - case 'P': destmode = Aipi; pos++; break; + case 'p': destmode = Apdi; pos++; break; + case 'P': destmode = Aipi; pos++; break; } break; - case '#': - switch(opcstr[pos++]) { - case 'z': destmode = imm; break; - case '0': destmode = imm0; break; - case '1': destmode = imm1; break; - case '2': destmode = imm2; 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; - case 'K': destmode = immi; destreg = bitval[bitK]; break; - default: abort(); + case 'L': + destmode = absl; + break; + case '#': + switch (opcstr[pos++]) { + case 'z': destmode = imm; break; + case '0': destmode = imm0; break; + case '1': destmode = imm1; break; + case '2': destmode = imm2; 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; + case 'K': destmode = immi; destreg = bitval[bitK]; break; + default: abort(); } break; - case 'd': + case 'd': destreg = bitval[bitD]; destmode = mode_from_mr(bitval[bitd],bitval[bitD]); - if(destmode == am_illg) continue; + 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[bitD]; - } + { + dstgather = 1; dstpos = bitpos[bitD]; + } if (opcstr[pos] == '[') { pos++; @@ -582,18 +620,19 @@ static void build_insn(int insn) if (destmode == imm || destmode == PC16 || destmode == PC8r) goto nomatch; break; - case 's': + case 's': destreg = bitval[bitS]; destmode = mode_from_mr(bitval[bits],bitval[bitS]); - if (destmode == am_illg) continue; + 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]; - } + { + dstgather = 1; dstpos = bitpos[bitS]; + } if (opcstr[pos] == '[') { pos++; @@ -628,15 +667,15 @@ static void build_insn(int insn) } } break; - default: abort(); + default: abort(); } /* safety check - might have changed */ if (destmode != Areg && destmode != Dreg && destmode != Aind && destmode != Ad16 && destmode != Ad8r && destmode != Aipi && destmode != Apdi) - { - dstgather = 0; - } + { + dstgather = 0; + } if (destmode == Areg && sz == sz_byte) goto nomatch; @@ -645,12 +684,12 @@ static void build_insn(int insn) dstgather = 0; } #endif - endofline: + endofline: /* now, we have a match */ if (table68k[opc].mnemo != i_ILLG) fprintf(stderr, "Double match: %x: %s\n", opc, opcstr); if (find == -1) { - for(find = 0;; find++) { + for (find = 0;; find++) { if (strcmp(mnemonic, lookuptab[find].name) == 0) { table68k[opc].mnemo = lookuptab[find].mnemo; break; @@ -666,9 +705,9 @@ static void build_insn(int insn) || table68k[opc].mnemo == i_BSET || table68k[opc].mnemo == i_BCLR || table68k[opc].mnemo == i_BCHG) - { - sz = destmode == Dreg ? sz_long : sz_byte; - } + { + sz = destmode == Dreg ? sz_long : sz_byte; + } table68k[opc].size = sz; table68k[opc].sreg = srcreg; table68k[opc].dreg = destreg; @@ -689,18 +728,19 @@ static void build_insn(int insn) #endif table68k[opc].flagdead = flagdead; table68k[opc].flaglive = flaglive; - nomatch: + table68k[opc].isjmp = isjmp; + nomatch: /* FOO! */; } } -void read_table68k () +void read_table68k (void) { int i; table68k = (struct instr *)xmalloc (65536 * sizeof (struct instr)); - for(i = 0; i < 65536; i++) { + for (i = 0; i < 65536; i++) { table68k[i].mnemo = i_ILLG; table68k[i].handler = -1; } @@ -711,7 +751,7 @@ void read_table68k () static int mismatch; -static void handle_merges(long int opcode) +static void handle_merges (long int opcode) { uae_u16 smsk; uae_u16 dmsk; @@ -734,6 +774,8 @@ static void handle_merges(long int opcod smsk = 7; sbitdst = 8; break; case 5: smsk = 63; sbitdst = 64; break; + case 7: + smsk = 3; sbitdst = 4; break; default: smsk = 0; sbitdst = 0; abort(); @@ -784,7 +826,7 @@ static void handle_merges(long int opcod } } -void do_merges () +void do_merges (void) { long int opcode; int nr = 0; @@ -798,7 +840,7 @@ void do_merges () nr_cpuop_funcs = nr; } -int get_no_mismatches () +int get_no_mismatches (void) { return mismatch; }