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

📄 prim_ops.c

📁 uboot1.3.0 for s3c2440, 支持nand flash启动
💻 C
📖 第 1 页 / 共 5 页
字号:
	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);    set_parity_flag(mod);    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);    set_parity_flag(mod);    M.x86.R_EAX = (u32)div;    M.x86.R_EDX = (u32)mod;}/****************************************************************************REMARKS:Implements the DIV instruction and side effects.****************************************************************************/void div_byte(u8 s){    u32 dvd, div, mod;    dvd = M.x86.R_AX;    if (s == 0) {	x86emu_intr_raise(0);	return;    }    div = dvd / (u8)s;    mod = dvd % (u8)s;    if (abs(div) > 0xff) {	x86emu_intr_raise(0);	return;    }    M.x86.R_AL = (u8)div;    M.x86.R_AH = (u8)mod;}/****************************************************************************REMARKS:Implements the DIV instruction and side effects.****************************************************************************/void div_word(u16 s){    u32 dvd, div, mod;    dvd = (((u32)M.x86.R_DX) << 16) | M.x86.R_AX;    if (s == 0) {	x86emu_intr_raise(0);	return;    }    div = dvd / (u16)s;    mod = dvd % (u16)s;    if (abs(div) > 0xffff) {	x86emu_intr_raise(0);	return;    }    CLEAR_FLAG(F_CF);    CLEAR_FLAG(F_SF);    CONDITIONAL_SET_FLAG(div == 0, F_ZF);    set_parity_flag(mod);    M.x86.R_AX = (u16)div;    M.x86.R_DX = (u16)mod;}/****************************************************************************REMARKS:Implements the DIV instruction and side effects.****************************************************************************/void div_long(u32 s){#ifdef	__HAS_LONG_LONG__    u64 dvd, div, mod;    dvd = (((u64)M.x86.R_EDX) << 32) | M.x86.R_EAX;    if (s == 0) {	x86emu_intr_raise(0);	return;    }    div = dvd / (u32)s;    mod = dvd % (u32)s;    if (abs(div) > 0xffffffff) {	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 h_s = s;    u32 l_s = 0;    int counter = 32;    int carry;    if (s == 0) {	x86emu_intr_raise(0);	return;    }    do {	div <<= 1;	carry = (l_dvd >= l_s) ? 0 : 1;	if (h_dvd < (h_s + carry)) {	    h_s >>= 1;	    l_s = s << (--counter);	    continue;	} else {	    h_dvd -= (h_s + carry);	    l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)		: (l_dvd - l_s);	    h_s >>= 1;	    l_s = s << (--counter);	    div |= 1;	    continue;	}    } while (counter > -1);    /* overflow */    if (h_dvd || (l_dvd > s)) {	x86emu_intr_raise(0);	return;    }    mod = l_dvd;#endif    CLEAR_FLAG(F_CF);    CLEAR_FLAG(F_AF);    CLEAR_FLAG(F_SF);    SET_FLAG(F_ZF);    set_parity_flag(mod);    M.x86.R_EAX = (u32)div;    M.x86.R_EDX = (u32)mod;}/****************************************************************************REMARKS:Implements the IN string instruction and side effects.****************************************************************************/static void single_in(int size){    if(size == 1)	store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inb)(M.x86.R_DX));    else if (size == 2)	store_data_word_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inw)(M.x86.R_DX));    else	store_data_long_abs(M.x86.R_ES, M.x86.R_DI,(*sys_inl)(M.x86.R_DX));}void ins(int size){    int inc = size;    if (ACCESS_FLAG(F_DF)) {	inc = -size;    }    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {	/* dont care whether REPE or REPNE */	/* in until CX is ZERO. */	u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?		     M.x86.R_ECX : M.x86.R_CX);	while (count--) {	  single_in(size);	  M.x86.R_DI += inc;	  }	M.x86.R_CX = 0;	if (M.x86.mode & SYSMODE_PREFIX_DATA) {	    M.x86.R_ECX = 0;	}	M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);    } else {	single_in(size);	M.x86.R_DI += inc;    }}/****************************************************************************REMARKS:Implements the OUT string instruction and side effects.****************************************************************************/static void single_out(int size){     if(size == 1)       (*sys_outb)(M.x86.R_DX,fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));     else if (size == 2)       (*sys_outw)(M.x86.R_DX,fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));     else       (*sys_outl)(M.x86.R_DX,fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));}void outs(int size){    int inc = size;    if (ACCESS_FLAG(F_DF)) {	inc = -size;    }    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {	/* dont care whether REPE or REPNE */	/* out until CX is ZERO. */	u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?		     M.x86.R_ECX : M.x86.R_CX);	while (count--) {	  single_out(size);	  M.x86.R_SI += inc;	  }	M.x86.R_CX = 0;	if (M.x86.mode & SYSMODE_PREFIX_DATA) {	    M.x86.R_ECX = 0;	}	M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);    } else {	single_out(size);	M.x86.R_SI += inc;    }}/****************************************************************************PARAMETERS:addr	- Address to fetch word fromREMARKS:Fetches a word from emulator memory using an absolute address.****************************************************************************/u16 mem_access_word(int addr){DB( if (CHECK_MEM_ACCESS())      x86emu_check_mem_access(addr);)    return (*sys_rdw)(addr);}/****************************************************************************REMARKS:Pushes a word onto the stack.NOTE: Do not inline this, as (*sys_wrX) is already inline!****************************************************************************/void push_word(u16 w){DB( if (CHECK_SP_ACCESS())      x86emu_check_sp_access();)    M.x86.R_SP -= 2;    (*sys_wrw)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP, w);}/****************************************************************************REMARKS:Pushes a long onto the stack.NOTE: Do not inline this, as (*sys_wrX) is already inline!****************************************************************************/void push_long(u32 w){DB( if (CHECK_SP_ACCESS())      x86emu_check_sp_access();)    M.x86.R_SP -= 4;    (*sys_wrl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP, w);}/****************************************************************************REMARKS:Pops a word from the stack.NOTE: Do not inline this, as (*sys_rdX) is already inline!****************************************************************************/u16 pop_word(void){    u16 res;DB( if (CHECK_SP_ACCESS())      x86emu_check_sp_access();)    res = (*sys_rdw)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);    M.x86.R_SP += 2;    return res;}/****************************************************************************REMARKS:Pops a long from the stack.NOTE: Do not inline this, as (*sys_rdX) is already inline!****************************************************************************/u32 pop_long(void){    u32 res;DB( if (CHECK_SP_ACCESS())      x86emu_check_sp_access();)    res = (*sys_rdl)(((u32)M.x86.R_SS << 4)  + M.x86.R_SP);    M.x86.R_SP += 4;    return res;}#endif

⌨️ 快捷键说明

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