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

📄 prim_ops.c

📁 uboot在arm处理器s3c2410的移植代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************						Realmode X86 Emulator Library**            	Copyright (C) 1996-1999 SciTech Software, Inc.* 				     Copyright (C) David Mosberger-Tang* 					   Copyright (C) 1999 Egbert Eich**  ========================================================================**  Permission to use, copy, modify, distribute, and sell this software and*  its documentation for any purpose is hereby granted without fee,*  provided that the above copyright notice appear in all copies and that*  both that copyright notice and this permission notice appear in*  supporting documentation, and that the name of the authors not be used*  in advertising or publicity pertaining to distribution of the software*  without specific, written prior permission.  The authors makes no*  representations about the suitability of this software for any purpose.*  It is provided "as is" without express or implied warranty.**  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR*  PERFORMANCE OF THIS SOFTWARE.**  ========================================================================** Language:		ANSI C* Environment:	Any* Developer:    Kendall Bennett** Description:  This file contains the code to implement the primitive*				machine operations used by the emulation code in ops.c** Carry Chain Calculation** This represents a somewhat expensive calculation which is* apparently required to emulate the setting of the OF and AF flag.* The latter is not so important, but the former is.  The overflow* flag is the XOR of the top two bits of the carry chain for an* addition (similar for subtraction).  Since we do not want to* simulate the addition in a bitwise manner, we try to calculate the* carry chain given the two operands and the result.** So, given the following table, which represents the addition of two* bits, we can derive a formula for the carry chain.** a   b   cin   r     cout* 0   0   0     0     0* 0   0   1     1     0* 0   1   0     1     0* 0   1   1     0     1* 1   0   0     1     0* 1   0   1     0     1* 1   1   0     0     1* 1   1   1     1     1** Construction of table for cout:** ab* r  \  00   01   11  10* |------------------* 0  |   0    1    1   1* 1  |   0    0    1   0** By inspection, one gets:  cc = ab +  r'(a + b)** That represents alot of operations, but NO CHOICE....** Borrow Chain Calculation.** The following table represents the subtraction of two bits, from* which we can derive a formula for the borrow chain.** a   b   bin   r     bout* 0   0   0     0     0* 0   0   1     1     1* 0   1   0     1     1* 0   1   1     0     1* 1   0   0     1     0* 1   0   1     0     0* 1   1   0     0     0* 1   1   1     1     1** Construction of table for cout:** ab* r  \  00   01   11  10* |------------------* 0  |   0    1    0   0* 1  |   1    1    1   0** By inspection, one gets:  bc = a'b +  r(a' + b)*****************************************************************************/#define	PRIM_OPS_NO_REDEFINE_ASM#include "x86emu/x86emui.h"/*------------------------- Global Variables ------------------------------*/#ifndef	__HAVE_INLINE_ASSEMBLER__static u32 x86emu_parity_tab[8] ={	0x96696996,	0x69969669,	0x69969669,	0x96696996,	0x69969669,	0x96696996,	0x96696996,	0x69969669,};#endif#define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)#define XOR2(x) 	(((x) ^ ((x)>>1)) & 0x1)/*----------------------------- Implementation ----------------------------*/#ifndef	__HAVE_INLINE_ASSEMBLER__/****************************************************************************REMARKS:Implements the AAA instruction and side effects.****************************************************************************/u16 aaa_word(u16 d){	u16	res;	if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {		d += 0x6;		d += 0x100;		SET_FLAG(F_AF);		SET_FLAG(F_CF);	} else {		CLEAR_FLAG(F_CF);		CLEAR_FLAG(F_AF);	}	res = (u16)(d & 0xFF0F);	CLEAR_FLAG(F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	return res;}/****************************************************************************REMARKS:Implements the AAA instruction and side effects.****************************************************************************/u16 aas_word(u16 d){	u16	res;	if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {		d -= 0x6;		d -= 0x100;		SET_FLAG(F_AF);		SET_FLAG(F_CF);	} else {		CLEAR_FLAG(F_CF);		CLEAR_FLAG(F_AF);	}	res = (u16)(d & 0xFF0F);	CLEAR_FLAG(F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	return res;}/****************************************************************************REMARKS:Implements the AAD instruction and side effects.****************************************************************************/u16 aad_word(u16 d){	u16 l;	u8 hb, lb;	hb = (u8)((d >> 8) & 0xff);	lb = (u8)((d & 0xff));	l = (u16)((lb + 10 * hb) & 0xFF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(l & 0x80, F_SF);	CONDITIONAL_SET_FLAG(l == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);	return l;}/****************************************************************************REMARKS:Implements the AAM instruction and side effects.****************************************************************************/u16 aam_word(u8 d){    u16 h, l;	h = (u16)(d / 10);	l = (u16)(d % 10);	l |= (u16)(h << 8);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	CLEAR_FLAG(F_OF);	CONDITIONAL_SET_FLAG(l & 0x80, F_SF);	CONDITIONAL_SET_FLAG(l == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);    return l;}/****************************************************************************REMARKS:Implements the ADC instruction and side effects.****************************************************************************/u8 adc_byte(u8 d, u8 s){	register u32 res;   /* all operands in native machine order */	register u32 cc;	if (ACCESS_FLAG(F_CF))		res = 1 + d + s;	else		res = d + s;	CONDITIONAL_SET_FLAG(res & 0x100, F_CF);	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* calculate the carry chain  SEE NOTE AT TOP. */	cc = (s & d) | ((~res) & (s | d));	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);	return (u8)res;}/****************************************************************************REMARKS:Implements the ADC instruction and side effects.****************************************************************************/u16 adc_word(u16 d, u16 s){	register u32 res;   /* all operands in native machine order */	register u32 cc;	if (ACCESS_FLAG(F_CF))		res = 1 + d + s;	else		res = d + s;	CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* calculate the carry chain  SEE NOTE AT TOP. */	cc = (s & d) | ((~res) & (s | d));	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);	return (u16)res;}/****************************************************************************REMARKS:Implements the ADC instruction and side effects.****************************************************************************/u32 adc_long(u32 d, u32 s){	register u32 lo;	/* all operands in native machine order */	register u32 hi;	register u32 res;	register u32 cc;	if (ACCESS_FLAG(F_CF)) {		lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);		res = 1 + d + s;		}	else {		lo = (d & 0xFFFF) + (s & 0xFFFF);		res = d + s;		}	hi = (lo >> 16) + (d >> 16) + (s >> 16);	CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* calculate the carry chain  SEE NOTE AT TOP. */	cc = (s & d) | ((~res) & (s | d));	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);	return res;}/****************************************************************************REMARKS:Implements the ADD instruction and side effects.****************************************************************************/u8 add_byte(u8 d, u8 s){	register u32 res;   /* all operands in native machine order */	register u32 cc;	res = d + s;	CONDITIONAL_SET_FLAG(res & 0x100, F_CF);	CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* calculate the carry chain  SEE NOTE AT TOP. */	cc = (s & d) | ((~res) & (s | d));	CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);	return (u8)res;}/****************************************************************************REMARKS:Implements the ADD instruction and side effects.****************************************************************************/u16 add_word(u16 d, u16 s){	register u32 res;   /* all operands in native machine order */	register u32 cc;	res = d + s;	CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);	CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	/* calculate the carry chain  SEE NOTE AT TOP. */	cc = (s & d) | ((~res) & (s | d));	CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);	return (u16)res;}/****************************************************************************REMARKS:Implements the ADD instruction and side effects.****************************************************************************/u32 add_long(u32 d, u32 s){	register u32 lo;	/* all operands in native machine order */	register u32 hi;	register u32 res;	register u32 cc;	lo = (d & 0xFFFF) + (s & 0xFFFF);	res = d + s;	hi = (lo >> 16) + (d >> 16) + (s >> 16);	CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);	CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);    /* calculate the carry chain  SEE NOTE AT TOP. */    cc = (s & d) | ((~res) & (s | d));	CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);	CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);    return res;}/****************************************************************************REMARKS:Implements the AND instruction and side effects.****************************************************************************/u8 and_byte(u8 d, u8 s){	register u8 res;    /* all operands in native machine order */	res = d & s;	/* set the flags  */	CLEAR_FLAG(F_OF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	CONDITIONAL_SET_FLAG(res & 0x80, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res), F_PF);	return res;}/****************************************************************************REMARKS:Implements the AND instruction and side effects.****************************************************************************/u16 and_word(u16 d, u16 s){    register u16 res;   /* all operands in native machine order */    res = d & s;    /* set the flags  */	CLEAR_FLAG(F_OF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);    return res;}/****************************************************************************REMARKS:Implements the AND instruction and side effects.****************************************************************************/u32 and_long(u32 d, u32 s){	register u32 res;   /* all operands in native machine order */	res = d & s;	/* set the flags  */	CLEAR_FLAG(F_OF);	CLEAR_FLAG(F_CF);	CLEAR_FLAG(F_AF);	CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);	CONDITIONAL_SET_FLAG(res == 0, F_ZF);	CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);	return res;}/****************************************************************************REMARKS:Implements the CMP instruction and side effects.****************************************************************************/u8 cmp_byte(u8 d, u8 s){	register u32 res;   /* all operands in native machine order */	register u32 bc;	res = d - s;	CLEAR_FLAG(F_CF);	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 d;}/****************************************************************************REMARKS:Implements the CMP instruction and side effects.****************************************************************************/u16 cmp_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);

⌨️ 快捷键说明

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