?? prim_ops.c
字號:
res = 0; CLEAR_FLAG(F_CF); SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); CLEAR_FLAG(F_PF); } } return (u16)res;}/****************************************************************************REMARKS:Implements the SAR instruction and side effects.****************************************************************************/u32 sar_long(u32 d, u8 s){ u32 cnt, res, cf, mask, sf; sf = d & 0x80000000; cnt = s % 32; res = d; if (cnt > 0 && cnt < 32) { mask = (1 << (32 - cnt)) - 1; cf = d & (1 << (cnt - 1)); res = (d >> cnt) & mask; CONDITIONAL_SET_FLAG(cf, F_CF); if (sf) { res |= ~mask; } set_szp_flags_32(res); } else if (cnt >= 32) { if (sf) { res = 0xffffffff; SET_FLAG(F_CF); CLEAR_FLAG(F_ZF); SET_FLAG(F_SF); SET_FLAG(F_PF); } else { res = 0; CLEAR_FLAG(F_CF); SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); CLEAR_FLAG(F_PF); } } return res;}/****************************************************************************REMARKS:Implements the SHLD instruction and side effects.****************************************************************************/u16 shld_word (u16 d, u16 fill, u8 s){ unsigned int cnt, res, cf; if (s < 16) { cnt = s % 16; if (cnt > 0) { res = (d << cnt) | (fill >> (16-cnt)); cf = d & (1 << (16 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); set_szp_flags_16((u16)res); } else { res = d; } if (cnt == 1) { CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^ (ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); } return (u16)res;}/****************************************************************************REMARKS:Implements the SHLD instruction and side effects.****************************************************************************/u32 shld_long (u32 d, u32 fill, u8 s){ unsigned int cnt, res, cf; if (s < 32) { cnt = s % 32; if (cnt > 0) { res = (d << cnt) | (fill >> (32-cnt)); cf = d & (1 << (32 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); set_szp_flags_32((u32)res); } else { res = d; } if (cnt == 1) { CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^ (ACCESS_FLAG(F_CF) != 0)), F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CONDITIONAL_SET_FLAG((d << (s-1)) & 0x80000000, F_CF); CLEAR_FLAG(F_OF); CLEAR_FLAG(F_SF); SET_FLAG(F_PF); SET_FLAG(F_ZF); } return res;}/****************************************************************************REMARKS:Implements the SHRD instruction and side effects.****************************************************************************/u16 shrd_word (u16 d, u16 fill, u8 s){ unsigned int cnt, res, cf; if (s < 16) { cnt = s % 16; if (cnt > 0) { cf = d & (1 << (cnt - 1)); res = (d >> cnt) | (fill << (16 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); set_szp_flags_16((u16)res); } else { res = d; } if (cnt == 1) { CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); CLEAR_FLAG(F_PF); } return (u16)res;}/****************************************************************************REMARKS:Implements the SHRD instruction and side effects.****************************************************************************/u32 shrd_long (u32 d, u32 fill, u8 s){ unsigned int cnt, res, cf; if (s < 32) { cnt = s % 32; if (cnt > 0) { cf = d & (1 << (cnt - 1)); res = (d >> cnt) | (fill << (32 - cnt)); CONDITIONAL_SET_FLAG(cf, F_CF); set_szp_flags_32((u32)res); } else { res = d; } if (cnt == 1) { CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF); } else { CLEAR_FLAG(F_OF); } } else { res = 0; CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); SET_FLAG(F_ZF); CLEAR_FLAG(F_SF); CLEAR_FLAG(F_PF); } return res;}/****************************************************************************REMARKS:Implements the SBB instruction and side effects.****************************************************************************/u8 sbb_byte(u8 d, u8 s){ u32 res; /* all operands in native machine order */ u32 bc; if (ACCESS_FLAG(F_CF)) res = d - s - 1; else res = d - s; set_szp_flags_8((u8)res); /* calculate the borrow chain. See note at top */ bc = (res & (~d | s)) | (~d & s); CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); return (u8)res;}/****************************************************************************REMARKS:Implements the SBB instruction and side effects.****************************************************************************/u16 sbb_word(u16 d, u16 s){ u32 res; /* all operands in native machine order */ u32 bc; if (ACCESS_FLAG(F_CF)) res = d - s - 1; else res = d - s; set_szp_flags_16((u16)res); /* calculate the borrow chain. See note at top */ bc = (res & (~d | s)) | (~d & s); CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); return (u16)res;}/****************************************************************************REMARKS:Implements the SBB instruction and side effects.****************************************************************************/u32 sbb_long(u32 d, u32 s){ u32 res; /* all operands in native machine order */ u32 bc; if (ACCESS_FLAG(F_CF)) res = d - s - 1; else res = d - s; set_szp_flags_32(res); /* calculate the borrow chain. See note at top */ bc = (res & (~d | s)) | (~d & s); CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); return res;}/****************************************************************************REMARKS:Implements the SUB instruction and side effects.****************************************************************************/u8 sub_byte(u8 d, u8 s){ u32 res; /* all operands in native machine order */ u32 bc; res = d - s; set_szp_flags_8((u8)res); /* calculate the borrow chain. See note at top */ bc = (res & (~d | s)) | (~d & s); CONDITIONAL_SET_FLAG(bc & 0x80, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); return (u8)res;}/****************************************************************************REMARKS:Implements the SUB instruction and side effects.****************************************************************************/u16 sub_word(u16 d, u16 s){ u32 res; /* all operands in native machine order */ u32 bc; res = d - s; set_szp_flags_16((u16)res); /* calculate the borrow chain. See note at top */ bc = (res & (~d | s)) | (~d & s); CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); return (u16)res;}/****************************************************************************REMARKS:Implements the SUB instruction and side effects.****************************************************************************/u32 sub_long(u32 d, u32 s){ u32 res; /* all operands in native machine order */ u32 bc; res = d - s; set_szp_flags_32(res); /* calculate the borrow chain. See note at top */ bc = (res & (~d | s)) | (~d & s); CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF); CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF); CONDITIONAL_SET_FLAG(bc & 0x8, F_AF); return res;}/****************************************************************************REMARKS:Implements the TEST instruction and side effects.****************************************************************************/void test_byte(u8 d, u8 s){ u32 res; /* all operands in native machine order */ res = d & s; CLEAR_FLAG(F_OF); set_szp_flags_8((u8)res); /* AF == dont care */ CLEAR_FLAG(F_CF);}/****************************************************************************REMARKS:Implements the TEST instruction and side effects.****************************************************************************/void test_word(u16 d, u16 s){ u32 res; /* all operands in native machine order */ res = d & s; CLEAR_FLAG(F_OF); set_szp_flags_16((u16)res); /* AF == dont care */ CLEAR_FLAG(F_CF);}/****************************************************************************REMARKS:Implements the TEST instruction and side effects.****************************************************************************/void test_long(u32 d, u32 s){ u32 res; /* all operands in native machine order */ res = d & s; CLEAR_FLAG(F_OF); set_szp_flags_32(res); /* AF == dont care */ CLEAR_FLAG(F_CF);}/****************************************************************************REMARKS:Implements the XOR instruction and side effects.****************************************************************************/u8 xor_byte(u8 d, u8 s){ u8 res; /* all operands in native machine order */ res = d ^ s; no_carry_byte_side_eff(res); return res;}/****************************************************************************REMARKS:Implements the XOR instruction and side effects.****************************************************************************/u16 xor_word(u16 d, u16 s){ u16 res; /* all operands in native machine order */ res = d ^ s; no_carry_word_side_eff(res); return res;}/****************************************************************************REMARKS:Implements the XOR instruction and side effects.****************************************************************************/u32 xor_long(u32 d, u32 s){ u32 res; /* all operands in native machine order */ res = d ^ s; no_carry_long_side_eff(res); return res;}/****************************************************************************REMARKS:Implements the IMUL instruction and side effects.****************************************************************************/void imul_byte(u8 s){ s16 res = (s16)((s8)M.x86.R_AL * (s8)s); M.x86.R_AX = res; if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) || ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); }}/****************************************************************************REMARKS:Implements the IMUL instruction and side effects.****************************************************************************/void imul_word(u16 s){ s32 res = (s16)M.x86.R_AX * (s16)s; M.x86.R_AX = (u16)res; M.x86.R_DX = (u16)(res >> 16); if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x0000) || ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFFFF)) { CLEAR_FLAG(F_CF); CLEAR_FLAG(F_OF); } else { SET_FLAG(F_CF); SET_FLAG(F_OF); }}/****************************************************************************REMARKS:Implements the IMUL instruction and side effects.****************************************************************************/void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s){#ifdef __HAS_LONG_LONG__ s64 res = (s32)d * (s32)s; *res_lo = (u32)res; *res_hi = (u32)(res >> 32);#else u32 d_lo,d_hi,d_sign; u32 s_lo,s_hi,s_sign; u32 rlo_lo,rlo_hi,rhi_lo; if ((d_sign = d & 0x80000000) != 0) d = -d; d_lo = d & 0xFFFF; d_hi = d >> 16; if ((s_sign = s & 0x80000000) != 0) s = -s; s_lo = s & 0xFFFF; s_hi = s >> 16; rlo_lo = d_lo * s_lo; rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16); rhi_lo = d_hi * s_hi + (rlo_hi >> 16); *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF); *res_hi = rhi_lo; if (d_sign != s_sign) { d = ~*res_lo; s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16); *res_lo = ~*res_lo+1; *res_hi = ~*res_hi+(s >> 16); }#endif}/****************************************************************************REMARKS:Implements the IMUL instruction and side effects.****************************************************************************/void imul_long(u32 s){ imul_long_direct(&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00000000) || ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFFFFFFFF)) { CLEAR_FLAG(F_CF);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -