⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prim_ops.c

📁 针对linux休眠suspend显卡状态保存恢复的一个办法
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************REMARKS:Implements the SUB instruction and side effects.****************************************************************************/u8 sub_byte(u8 d, u8 s){	register u32 res;   /* all operands in native machine order */	register u32 bc;	res = d - s;	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* 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){    register u32 res;   /* all operands in native machine order */    register u32 bc;    res = d - s;	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* 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){	register u32 res;   /* all operands in native machine order */	register u32 bc;	res = d - s;	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* 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){    register u32 res;   /* all operands in native machine order */    res = d & s;	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);    /* AF == dont care */	CLEAR_FLAG(F_CF);}/****************************************************************************REMARKS:Implements the TEST instruction and side effects.****************************************************************************/void test_word(u16 d, u16 s){	register u32 res;   /* all operands in native machine order */	res = d & s;	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* AF == dont care */	CLEAR_FLAG(F_CF);}/****************************************************************************REMARKS:Implements the TEST instruction and side effects.****************************************************************************/void test_long(u32 d, u32 s){	register u32 res;   /* all operands in native machine order */	res = d & s;	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* AF == dont care */	CLEAR_FLAG(F_CF);}/****************************************************************************REMARKS:Implements the XOR instruction and side effects.****************************************************************************/u8 xor_byte(u8 d, u8 s){	register u8 res;    /* all operands in native machine order */	res = d ^ s;	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	return res;}/****************************************************************************REMARKS:Implements the XOR instruction and side effects.****************************************************************************/u16 xor_word(u16 d, u16 s){	register u16 res;   /* all operands in native machine order */	res = d ^ s;	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	return res;}/****************************************************************************REMARKS:Implements the XOR instruction and side effects.****************************************************************************/u32 xor_long(u32 d, u32 s){	register u32 res;   /* all operands in native machine order */	res = d ^ s;	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	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 == 0x00) ||		((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 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_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 == 0x00) ||		((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {		CLEAR_FLAG(F_CF);		CLEAR_FLAG(F_OF);	} else {		SET_FLAG(F_CF);		SET_FLAG(F_OF);	}}/****************************************************************************REMARKS:Implements the MUL instruction and side effects.****************************************************************************/void mul_byte(u8 s){	u16 res = (u16)(M.x86.R_AL * s);	M.x86.R_AX = res;	if (M.x86.R_AH == 0) {		CLEAR_FLAG(F_CF);		CLEAR_FLAG(F_OF);	} else {		SET_FLAG(F_CF);		SET_FLAG(F_OF);	}}/****************************************************************************REMARKS:Implements the MUL instruction and side effects.****************************************************************************/void mul_word(u16 s){	u32 res = M.x86.R_AX * s;	M.x86.R_AX = (u16)res;	M.x86.R_DX = (u16)(res >> 16);	if (M.x86.R_DX == 0) {		CLEAR_FLAG(F_CF);		CLEAR_FLAG(F_OF);    } else {		SET_FLAG(F_CF);		SET_FLAG(F_OF);    }}/****************************************************************************REMARKS:Implements the MUL instruction and side effects.****************************************************************************/void mul_long(u32 s){#ifdef	__HAS_LONG_LONG__	u64 res = (u32)M.x86.R_EAX * (u32)s;	M.x86.R_EAX = (u32)res;	M.x86.R_EDX = (u32)(res >> 32);#else	u32	a,a_lo,a_hi;	u32	s_lo,s_hi;	u32	rlo_lo,rlo_hi,rhi_lo;	a = M.x86.R_EAX;	a_lo = a & 0xFFFF;	a_hi = a >> 16;	s_lo = s & 0xFFFF;	s_hi = s >> 16;	rlo_lo = a_lo * s_lo;	rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);	rhi_lo = a_hi * s_hi + (rlo_hi >> 16);	M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);	M.x86.R_EDX = rhi_lo;#endif	if (M.x86.R_EDX == 0) {		CLEAR_FLAG(F_CF);		CLEAR_FLAG(F_OF);	} else {		SET_FLAG(F_CF);		SET_FLAG(F_OF);    }}/****************************************************************************REMARKS:Implements the IDIV instruction and side effects.****************************************************************************/void idiv_byte(u8 s){    s32 dvd, div, mod;	dvd = (s16)M.x86.R_AX;	if (s == 0) {		x86emu_intr_raise(0);        return;	}	div = dvd / (s8)s;	mod = dvd % (s8)s;	if (abs(div) > 0x7f) {		x86emu_intr_raise(0);		return;	}	M.x86.R_AL = (s8) div;	M.x86.R_AH = (s8) mod;}/****************************************************************************REMARKS:Implements the IDIV instruction and side effects.****************************************************************************/void idiv_word(u16 s){	s32 dvd, div, mod;	dvd = (((s32)M.x86.R_DX) << 16) | M.x86.R_AX;	if (s == 0) {		x86emu_intr_raise(0);		return;	}	div = dvd / (s16)s;	mod = dvd % (s16)s;	if (abs(div) > 0x7fff) {		x86emu_intr_raise(0);		return;	}	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_SF);	CONDITIONAL_SET_FLAG(div == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);	M.x86.R_AX = (u16)div;	M.x86.R_DX = (u16)mod;}/****************************************************************************REMARKS:Implements the IDIV instruction and side effects.****************************************************************************/void idiv_long(u32 s){#ifdef	__HAS_LONG_LONG__	s64 dvd, div, mod;	dvd = (((s64)M.x86.R_EDX) << 32) | M.x86.R_EAX;	if (s == 0) {		x86emu_intr_raise(0);		return;	}	div = dvd / (s32)s;	mod = dvd % (s32)s;	if (abs(div) > 0x7fffffff) {		x86emu_intr_raise(0);		return;	}#else	s32 div = 0, mod;	s32 h_dvd = M.x86.R_EDX;	u32 l_dvd = M.x86.R_EAX;	u32 abs_s = s & 0x7FFFFFFF;	u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;	u32 h_s = abs_s >> 1;	u32 l_s = abs_s << 31;	int counter = 31;	int carry;	if (s == 0) {		x86emu_intr_raise(0);		return;	}	do {		div <<= 1;		carry = (l_dvd >= l_s) ? 0 : 1;				if (abs_h_dvd < (h_s + carry)) {			h_s >>= 1;			l_s = abs_s << (--counter);			continue;		} else {			abs_h_dvd -= (h_s + carry);			l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)				: (l_dvd - l_s);			h_s >>= 1;			l_s = abs_s << (--counter);			div |= 1;			continue;		}			} while (counter > -1);	/* overflow */	if (abs_h_dvd || (l_dvd > abs_s)) {		x86emu_intr_raise(0);		return;	}	/* sign */	div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));	mod = l_dvd;#endif	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	CLEAR_FLAG(F_SF);	SET_FLAG(F_ZF);	CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);	M.x86.R_EAX = (u32)div;	M.x86.R_EDX =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -