Skip to content

Commit

Permalink
Store OF and CF as bytes for improved efficiency
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed May 13, 2018
1 parent 35b6316 commit 816ed11
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 16 deletions.
17 changes: 13 additions & 4 deletions emu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct cpu_state {
union {
dword_t eflags;
struct {
bits cf:1;
bits cf_bit:1;
bits pad1_1:1;
bits pf:1;
bits pad2_0:1;
Expand All @@ -68,18 +68,19 @@ struct cpu_state {
bits tf:1;
bits if_:1;
bits df:1;
bits of:1;
bits of_bit:1;
bits iopl:2;
};
};
// for maximum efficiency these are stored in bytes
byte_t cf;
byte_t of;
// whether the true flag values are in the above struct, or computed from
// the stored result and operands
dword_t res, op1, op2;
bits pf_res:1;
bits zf_res:1;
bits sf_res:1;
bits cf_ops:1;
bits of_ops:1;
bits af_ops:1;

// fpu
Expand Down Expand Up @@ -142,13 +143,21 @@ static inline void collapse_flags(struct cpu_state *cpu) {
cpu->sf = SF;
cpu->pf = PF;
cpu->zf_res = cpu->sf_res = cpu->pf_res = 0;
cpu->of_bit = cpu->of;
cpu->cf_bit = cpu->cf;
cpu->af = AF;
cpu->af_ops = 0;
cpu->pad1_1 = 1;
cpu->pad2_0 = cpu->pad3_0 = 0;
cpu->if_ = 1;
}

static inline void expand_flags(struct cpu_state *cpu) {
cpu->of = cpu->of_bit;
cpu->cf = cpu->cf_bit;
cpu->zf_res = cpu->sf_res = cpu->pf_res = cpu->af_ops = 0;
}

enum reg32 {
reg_eax = 0, reg_ecx, reg_edx, reg_ebx, reg_esp, reg_ebp, reg_esi, reg_edi, reg_cnt,
reg_none = reg_cnt,
Expand Down
20 changes: 10 additions & 10 deletions emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,13 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
#define MUL1(val,z) do { \
uint64_t tmp = cpu->oax * (uint64_t) get(val,z); \
cpu->oax = tmp; cpu->odx = tmp >> sz(z); \
cpu->cf = cpu->of = (tmp != (uint32_t) tmp); cpu->cf_ops = cpu->of_ops = 0; ZEROAF; \
cpu->cf = cpu->of = (tmp != (uint32_t) tmp); ZEROAF; \
cpu->zf = cpu->sf = cpu->pf = cpu->zf_res = cpu->sf_res = cpu->pf_res = 0; \
} while (0)
#define IMUL1(val,z) do { \
int64_t tmp = (int64_t) (sint(sz(z))) cpu->oax * (sint(sz(z))) get(val,z); \
cpu->oax = tmp; cpu->odx = tmp >> sz(z); \
cpu->cf = cpu->of = (tmp != (int32_t) tmp); cpu->cf_ops = cpu->of_ops = 0; \
cpu->cf = cpu->of = (tmp != (int32_t) tmp); \
cpu->zf = cpu->sf = cpu->pf = cpu->zf_res = cpu->sf_res = cpu->pf_res = 0; \
} while (0)
#define MUL2(val, reg) \
Expand Down Expand Up @@ -362,15 +362,15 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
int cnt = get(count,z) % sz(z); \
/* the compiler miraculously turns this into a rol instruction with optimizations on */\
set(val, get(val,z) << cnt | get(val,z) >> (sz(z) - cnt),z); \
cpu->cf = get(val,z) & 1; cpu->cf_ops = 0; \
if (cnt == 1) { cpu->of = cpu->cf ^ (get(val,z) >> (OP_SIZE - 1)); cpu->of_ops = 0; } \
cpu->cf = get(val,z) & 1; \
if (cnt == 1) { cpu->of = cpu->cf ^ (get(val,z) >> (OP_SIZE - 1)); } \
}
#define ROR(count, val,z) \
if (get(count,z) % sz(z) != 0) { \
int cnt = get(count,z) % sz(z); \
set(val, get(val,z) >> cnt | get(val,z) << (sz(z) - cnt),z); \
cpu->cf = get(val,z) >> (OP_SIZE - 1); cpu->cf_ops = 0; \
if (cnt == 1) { cpu->of = cpu->cf ^ (get(val,z) & 1); cpu->of_ops = 0; } \
cpu->cf = get(val,z) >> (OP_SIZE - 1); \
if (cnt == 1) { cpu->of = cpu->cf ^ (get(val,z) & 1); } \
}
#define SHL(count, val,z) \
if (get(count,z) % sz(z) != 0) { \
Expand All @@ -396,7 +396,7 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
#define SHRD(count, extra, dst,z) \
if (get(count,z) % sz(z) != 0) { \
int cnt = get(count,z) % sz(z); \
cpu->cf = (get(dst,z) >> (cnt - 1)) & 1; cpu->cf_ops = 0; \
cpu->cf = (get(dst,z) >> (cnt - 1)) & 1; \
cpu->res = get(dst,z) >> cnt | get(extra,z) << (sz(z) - cnt); \
set(dst, cpu->res,z); \
SETRESFLAGS; \
Expand Down Expand Up @@ -573,7 +573,7 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o

#define POPF() \
POP(eflags); \
cpu->zf_res = cpu->sf_res = cpu->pf_res = cpu->af_ops = 0
expand_flags(cpu)

#define PUSHF() \
collapse_flags(cpu); \
Expand All @@ -586,7 +586,7 @@ static bool modrm_compute(struct cpu_state *cpu, struct tlb *tlb, addr_t *addr_o
#define SAHF \
cpu->eflags &= 0xffffff00 | ~AH_FLAG_MASK; \
cpu->eflags |= cpu->ah & AH_FLAG_MASK; \
cpu->cf_ops = cpu->pf_res = cpu->af_ops = cpu->zf_res = cpu->sf_res = 0
expand_flags(cpu)

#define RDTSC \
imm = rdtsc(); \
Expand Down Expand Up @@ -660,4 +660,4 @@ flatten __no_instrument void cpu_run(struct cpu_state *cpu) {
}
}

int log_override = 0;
/* int log_override = 0; */
4 changes: 2 additions & 2 deletions emu/interp/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ static inline extFloat80_t extF80_abs(extFloat80_t f) {
ST(0) = extF80_rem(ST(0), ST(1))

#define FUCOMI() \
cpu->zf = extF80_eq(ST(0), ST_i); cpu->zf_res = 0; \
cpu->cf = extF80_lt(ST(0), ST_i); cpu->cf_ops = 0; \
cpu->zf = extF80_eq(ST(0), ST_i); \
cpu->cf = extF80_lt(ST(0), ST_i); \
cpu->pf = 0; cpu->pf_res = 0
// not worrying about nans and shit yet

Expand Down

0 comments on commit 816ed11

Please sign in to comment.