diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64primop.h | 192 | ||||
| -rw-r--r-- | src/emu/x64run66.c | 4 | ||||
| -rw-r--r-- | src/emu/x64run_private.c | 137 |
3 files changed, 246 insertions, 87 deletions
diff --git a/src/emu/x64primop.h b/src/emu/x64primop.h index a0f465a3..83f8b00b 100644 --- a/src/emu/x64primop.h +++ b/src/emu/x64primop.h @@ -304,145 +304,193 @@ uint64_t sbb64 (x64emu_t *emu, uint64_t d, uint64_t s); static inline uint8_t shl8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->df = d_shl8; - emu->op1.u8 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u8 = s; - emu->res.u8 = d << s; + emu->df = d_shl8; + emu->op1.u8 = d; + emu->op2.u8 = s; + emu->res.u8 = d << s; - return emu->res.u8; + return emu->res.u8; + } else + return d; } static inline uint16_t shl16(x64emu_t *emu, uint16_t d, uint8_t s) { - emu->df = d_shl16; - emu->op1.u16 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u16 = s; - emu->res.u16 = d << s; - return emu->res.u16; + emu->df = d_shl16; + emu->op1.u16 = d; + emu->op2.u16 = s; + emu->res.u16 = d << s; + return emu->res.u16; + } else + return d; } static inline uint32_t shl32(x64emu_t *emu, uint32_t d, uint8_t s) { - emu->df = d_shl32; - emu->op1.u32 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u32 = s; - emu->res.u32 = d << s; + emu->df = d_shl32; + emu->op1.u32 = d; + emu->op2.u32 = s; + emu->res.u32 = d << s; - return emu->res.u32; + return emu->res.u32; + } else + return d; } static inline uint64_t shl64(x64emu_t *emu, uint64_t d, uint8_t s) { - emu->df = d_shl64; - emu->op1.u64 = d; + if(s&0x3f) { + s &= 0x3f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x3f; - emu->op2.u64 = s; - emu->res.u64 = d << s; + emu->df = d_shl64; + emu->op1.u64 = d; + emu->op2.u64 = s; + emu->res.u64 = d << s; - return emu->res.u64; + return emu->res.u64; + } else + return d; } static inline uint8_t shr8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->df = d_shr8; - emu->op1.u8 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u8 = s; - emu->res.u8 = d >> s; + emu->df = d_shr8; + emu->op1.u8 = d; + emu->op2.u8 = s; + emu->res.u8 = d >> s; - return emu->res.u8; + return emu->res.u8; + } else + return d; } static inline uint16_t shr16(x64emu_t *emu, uint16_t d, uint8_t s) { - emu->df = d_shr16; - emu->op1.u16 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u16 = s; - emu->res.u16 = d >> s; + emu->df = d_shr16; + emu->op1.u16 = d; + emu->op2.u16 = s; + emu->res.u16 = d >> s; - return emu->res.u16; + return emu->res.u16; + } else + return d; } static inline uint32_t shr32(x64emu_t *emu, uint32_t d, uint8_t s) { - emu->df = d_shr32; - emu->op1.u32 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u32 = s; - emu->res.u32 = d >> s; + emu->df = d_shr32; + emu->op1.u32 = d; + emu->op2.u32 = s; + emu->res.u32 = d >> s; - return emu->res.u32; + return emu->res.u32; + } else + return d; } static inline uint64_t shr64(x64emu_t *emu, uint64_t d, uint8_t s) { - emu->df = d_shr64; - emu->op1.u64 = d; + if(s&0x3f) { + s &= 0x3f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x3f; - emu->op2.u64 = s; - emu->res.u64 = d >> s; + emu->df = d_shr64; + emu->op1.u64 = d; + emu->op2.u64 = s; + emu->res.u64 = d >> s; - return emu->res.u64; + return emu->res.u64; + } else + return d; } static inline uint8_t sar8(x64emu_t *emu, uint8_t d, uint8_t s) { - emu->df = d_sar8; - emu->op1.u8 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u8 = s; - emu->res.u8 = (uint8_t)(((int8_t)d)>>s); + emu->df = d_sar8; + emu->op1.u8 = d; + emu->op2.u8 = s; + emu->res.u8 = (uint8_t)(((int8_t)d)>>s); - return emu->res.u8; + return emu->res.u8; + } else + return d; } static inline uint16_t sar16(x64emu_t *emu, uint16_t d, uint8_t s) { - emu->df = d_sar16; - emu->op1.u16 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u16 = s; - emu->res.u16 = (uint16_t)(((int16_t)d)>>s); + emu->df = d_sar16; + emu->op1.u16 = d; + emu->op2.u16 = s; + emu->res.u16 = (uint16_t)(((int16_t)d)>>s); - return emu->res.u16; + return emu->res.u16; + } else + return d; } static inline uint32_t sar32(x64emu_t *emu, uint32_t d, uint8_t s) { - emu->df = d_sar32; - emu->op1.u32 = d; + if(s&0x1f) { + s &= 0x1f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x1f; - emu->op2.u32 = s; - emu->res.u32 = (uint32_t)(((int32_t)d)>>s); + emu->df = d_sar32; + emu->op1.u32 = d; + emu->op2.u32 = s; + emu->res.u32 = (uint32_t)(((int32_t)d)>>s); - return emu->res.u32; + return emu->res.u32; + } else + return d; } static inline uint64_t sar64(x64emu_t *emu, uint64_t d, uint8_t s) { - emu->df = d_sar64; - emu->op1.u64 = d; + if(s&0x3f) { + s &= 0x3f; + if(s!=1) CHECK_FLAGS(emu); // for OF, need to find something more elegant here, using sav stuffs - s &= 0x3f; - emu->op2.u64 = s; - emu->res.u64 = (uint64_t)(((int64_t)d)>>s); + emu->df = d_sar64; + emu->op1.u64 = d; + emu->op2.u64 = s; + emu->res.u64 = (uint64_t)(((int64_t)d)>>s); - return emu->res.u64; + return emu->res.u64; + } else + return d; } static inline uint8_t sub8(x64emu_t *emu, uint8_t d, uint8_t s) diff --git a/src/emu/x64run66.c b/src/emu/x64run66.c index 79553512..3ba3af50 100644 --- a/src/emu/x64run66.c +++ b/src/emu/x64run66.c @@ -218,8 +218,8 @@ uintptr_t Run66(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) case 0x56: case 0x57: /* PUSH Reg */ if(rex.is32bits) { - tmp8u = opcode&7; - Push16(emu, emu->regs[tmp8u].word[0]); + tmp16u = emu->regs[opcode&7].word[0]; + Push16(emu, tmp16u); } else return 0; break; diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index bb18971a..fa61d2c1 100644 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -297,7 +297,13 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_imul16: lo = (uint16_t)emu->res.u32; @@ -310,18 +316,30 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_imul32: - if (((emu->res.u32 & 0x80000000) == 0 && emu->op1.u32 == 0x00) || - ((emu->res.u32 & 0x80000000) != 0 && emu->op1.u32 == 0xFFFFFFFF)) { + if ((((emu->res.u32 & 0x80000000) == 0) && emu->op1.u32 == 0x00) || + (((emu->res.u32 & 0x80000000) != 0) && emu->op1.u32 == 0xFFFFFFFF)) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); - SET_FLAG(F_OF); + SET_FLAG(F_OF); + } + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); break; case d_imul64: if (((emu->res.u64 & 0x8000000000000000LL) == 0 && emu->op1.u64 == 0x00) || @@ -332,7 +350,13 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_mul8: lo = emu->res.u16 & 0xff; @@ -344,7 +368,13 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_mul16: lo = (uint16_t)emu->res.u32; @@ -356,7 +386,13 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(lo & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_mul32: if (emu->op1.u32 == 0) { @@ -366,7 +402,13 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_mul64: if (emu->op1.u64 == 0) { @@ -376,7 +418,13 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_CF); SET_FLAG(F_OF); } - CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); + if(box64_dynarec_test) { + // to avoid noise in tests + CLEAR_FLAG(F_SF); + CLEAR_FLAG(F_ZF); + CLEAR_FLAG(F_AF); + CLEAR_FLAG(F_PF); + } break; case d_or8: CLEAR_FLAG(F_OF); @@ -460,6 +508,9 @@ void UpdateFlags(x64emu_t *emu) } else { CLEAR_FLAG(F_OF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } } else { CONDITIONAL_SET_FLAG((emu->op1.u8 << (emu->op2.u8-1)) & 0x80, F_CF); @@ -467,6 +518,9 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shl16: @@ -483,6 +537,9 @@ void UpdateFlags(x64emu_t *emu) } else { CLEAR_FLAG(F_OF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } } else { CONDITIONAL_SET_FLAG((emu->op1.u16 << (emu->op2.u16-1)) & 0x8000, F_CF); @@ -490,6 +547,9 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shl32: @@ -507,6 +567,9 @@ void UpdateFlags(x64emu_t *emu) } else { CLEAR_FLAG(F_OF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } } else { CONDITIONAL_SET_FLAG((emu->op1.u32 << (emu->op2.u32-1)) & 0x80000000, F_CF); @@ -514,6 +577,9 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shl64: @@ -529,6 +595,9 @@ void UpdateFlags(x64emu_t *emu) } else { CLEAR_FLAG(F_OF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_sar8: @@ -541,19 +610,25 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); if(emu->op2.u8==1) CLEAR_FLAG(F_OF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } } else { if (emu->op1.u8&0x80) { SET_FLAG(F_CF); - CLEAR_FLAG(F_ZF); SET_FLAG(F_SF); + CLEAR_FLAG(F_ZF); SET_FLAG(F_PF); } else { CLEAR_FLAG(F_CF); - SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); + SET_FLAG(F_ZF); SET_FLAG(F_PF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_sar16: @@ -566,6 +641,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); if(emu->op2.u16==1) CLEAR_FLAG(F_OF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } } else { if (emu->op1.u16&0x8000) { @@ -579,6 +657,9 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_SF); SET_FLAG(F_PF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_sar32: @@ -591,6 +672,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); if(emu->op2.u32==1) CLEAR_FLAG(F_OF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } } else { if (emu->op1.u32&0x80000000) { @@ -604,6 +688,9 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_SF); SET_FLAG(F_PF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_sar64: @@ -615,6 +702,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG(PARITY(emu->res.u64 & 0xff), F_PF); if(emu->op2.u64==1) CLEAR_FLAG(F_OF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shr8: @@ -626,6 +716,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u8 & 0xff) == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u8 & 0x80, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u8 & 0xff), F_PF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } if (cnt == 1) { CONDITIONAL_SET_FLAG(emu->op1.u8 & 0x80, F_OF); @@ -635,6 +728,9 @@ void UpdateFlags(x64emu_t *emu) CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shr16: @@ -646,6 +742,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u16 & 0xffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u16 & 0x8000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u16 & 0xff), F_PF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } if (cnt == 1) { CONDITIONAL_SET_FLAG(emu->op1.u16 & 0x8000, F_OF); @@ -655,6 +754,9 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shr32: @@ -666,6 +768,9 @@ void UpdateFlags(x64emu_t *emu) CONDITIONAL_SET_FLAG((emu->res.u32 & 0xffffffff) == 0, F_ZF); CONDITIONAL_SET_FLAG(emu->res.u32 & 0x80000000, F_SF); CONDITIONAL_SET_FLAG(PARITY(emu->res.u32 & 0xff), F_PF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } if (cnt == 1) { CONDITIONAL_SET_FLAG(emu->op1.u32 & 0x80000000, F_OF); @@ -675,6 +780,9 @@ void UpdateFlags(x64emu_t *emu) SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shr64: @@ -688,6 +796,9 @@ void UpdateFlags(x64emu_t *emu) if (cnt == 1) { CONDITIONAL_SET_FLAG(emu->op1.u64 & 0x8000000000000000LL, F_OF); } + if(box64_dynarec_test) { + CLEAR_FLAG(F_AF); + } } break; case d_shrd16: |