--- np2/i386c/ia32/instructions/data_trans.c 2004/03/12 13:34:08 1.13 +++ np2/i386c/ia32/instructions/data_trans.c 2004/05/22 16:35:07 1.16 @@ -1,4 +1,4 @@ -/* $Id: data_trans.c,v 1.13 2004/03/12 13:34:08 monaka Exp $ */ +/* $Id: data_trans.c,v 1.16 2004/05/22 16:35:07 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -153,7 +153,6 @@ MOV_EdSw(void) } else { CPU_WORKCLOCK(3); madr = calc_ea_dst(op); - // LSB only... cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); } return; @@ -374,7 +373,7 @@ CMOVO_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (CPU_OV) { + if (CC_O) { *out = (UINT16)src; } } @@ -386,7 +385,7 @@ CMOVO_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (CPU_OV) { + if (CC_O) { *out = src; } } @@ -398,7 +397,7 @@ CMOVNO_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (!CPU_OV) { + if (CC_NO) { *out = (UINT16)src; } } @@ -410,7 +409,7 @@ CMOVNO_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (!CPU_OV) { + if (CC_NO) { *out = src; } } @@ -422,7 +421,7 @@ CMOVC_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (CPU_FLAGL & C_FLAG) { + if (CC_C) { *out = (UINT16)src; } } @@ -434,7 +433,7 @@ CMOVC_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (CPU_FLAGL & C_FLAG) { + if (CC_C) { *out = src; } } @@ -446,7 +445,7 @@ CMOVNC_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & C_FLAG)) { + if (CC_NC) { *out = (UINT16)src; } } @@ -458,7 +457,7 @@ CMOVNC_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & C_FLAG)) { + if (CC_NC) { *out = src; } } @@ -470,7 +469,7 @@ CMOVZ_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (CPU_FLAGL & Z_FLAG) { + if (CC_Z) { *out = (UINT16)src; } } @@ -482,7 +481,7 @@ CMOVZ_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (CPU_FLAGL & Z_FLAG) { + if (CC_Z) { *out = src; } } @@ -494,7 +493,7 @@ CMOVNZ_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & Z_FLAG)) { + if (CC_NZ) { *out = (UINT16)src; } } @@ -506,7 +505,7 @@ CMOVNZ_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & Z_FLAG)) { + if (CC_NZ) { *out = src; } } @@ -518,7 +517,7 @@ CMOVA_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + if (CC_A) { *out = (UINT16)src; } } @@ -530,7 +529,7 @@ CMOVA_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) { + if (CC_A) { *out = src; } } @@ -542,7 +541,7 @@ CMOVNA_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + if (CC_NA) { *out = (UINT16)src; } } @@ -554,7 +553,7 @@ CMOVNA_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (CPU_FLAGL & (Z_FLAG | C_FLAG)) { + if (CC_NA) { *out = src; } } @@ -566,7 +565,7 @@ CMOVS_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (CPU_FLAGL & S_FLAG) { + if (CC_S) { *out = (UINT16)src; } } @@ -578,7 +577,7 @@ CMOVS_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (CPU_FLAGL & S_FLAG) { + if (CC_S) { *out = src; } } @@ -590,7 +589,7 @@ CMOVNS_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & S_FLAG)) { + if (CC_NS) { *out = (UINT16)src; } } @@ -602,7 +601,7 @@ CMOVNS_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & S_FLAG)) { + if (CC_NS) { *out = src; } } @@ -614,7 +613,7 @@ CMOVP_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (CPU_FLAGL & P_FLAG) { + if (CC_P) { *out = (UINT16)src; } } @@ -626,7 +625,7 @@ CMOVP_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (CPU_FLAGL & P_FLAG) { + if (CC_P) { *out = src; } } @@ -638,7 +637,7 @@ CMOVNP_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & P_FLAG)) { + if (CC_NP) { *out = (UINT16)src; } } @@ -650,7 +649,7 @@ CMOVNP_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if (!(CPU_FLAGL & P_FLAG)) { + if (CC_NP) { *out = src; } } @@ -662,7 +661,7 @@ CMOVL_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if ((!CPU_OV) != (!(CPU_FLAGL & S_FLAG))) { + if (CC_L) { *out = (UINT16)src; } } @@ -674,7 +673,7 @@ CMOVL_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if ((!CPU_OV) != (!(CPU_FLAGL & S_FLAG))) { + if (CC_L) { *out = src; } } @@ -686,7 +685,7 @@ CMOVNL_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if ((!CPU_OV) == (!(CPU_FLAGL & S_FLAG))) { + if (CC_NL) { *out = (UINT16)src; } } @@ -698,7 +697,7 @@ CMOVNL_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if ((!CPU_OV) == (!(CPU_FLAGL & S_FLAG))) { + if (CC_NL) { *out = src; } } @@ -710,7 +709,7 @@ CMOVLE_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + if (CC_LE) { *out = (UINT16)src; } } @@ -722,7 +721,7 @@ CMOVLE_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if ((CPU_FLAGL & Z_FLAG) || ((!(CPU_FLAGL & S_FLAG)) != (!CPU_OV))) { + if (CC_LE) { *out = src; } } @@ -734,7 +733,7 @@ CMOVNLE_GwEw(void) UINT32 op, src; PREPART_REG16_EA(op, src, out, 2, 5); - if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + if (CC_NLE) { *out = (UINT16)src; } } @@ -746,7 +745,7 @@ CMOVNLE_GdEd(void) UINT32 op, src; PREPART_REG32_EA(op, src, out, 2, 5); - if ((!(CPU_FLAGL & Z_FLAG)) && ((!(CPU_FLAGL & S_FLAG)) == (!CPU_OV))) { + if (CC_NLE) { *out = src; } } @@ -754,12 +753,19 @@ CMOVNLE_GdEd(void) /* * XCHG */ +static UINT32 +XCHG(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + (void)dst; + return src; +} + void XCHG_EbGb(void) { UINT8 *out, *src; UINT32 op, madr; - UINT8 tmp; PREPART_EA_REG8P(op, src); if (op >= 0xc0) { @@ -769,9 +775,7 @@ XCHG_EbGb(void) } else { CPU_WORKCLOCK(5); madr = calc_ea_dst(op); - tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, *src); - *src = tmp; + *src = (UINT8)cpu_memory_access_va_RMW(CPU_INST_SEGREG_INDEX, madr, XCHG, UINT32_TO_PTR(*src)); } } @@ -780,7 +784,6 @@ XCHG_EwGw(void) { UINT16 *out, *src; UINT32 op, madr; - UINT16 tmp; PREPART_EA_REG16P(op, src); if (op >= 0xc0) { @@ -790,9 +793,7 @@ XCHG_EwGw(void) } else { CPU_WORKCLOCK(5); madr = calc_ea_dst(op); - tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, *src); - *src = tmp; + *src = (UINT16)cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, XCHG, UINT32_TO_PTR(*src)); } } @@ -801,7 +802,6 @@ XCHG_EdGd(void) { UINT32 *out, *src; UINT32 op, madr; - UINT32 tmp; PREPART_EA_REG32P(op, src); if (op >= 0xc0) { @@ -811,9 +811,7 @@ XCHG_EdGd(void) } else { CPU_WORKCLOCK(5); madr = calc_ea_dst(op); - tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, *src); - *src = tmp; + *src = cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, XCHG, UINT32_TO_PTR(*src)); } } @@ -844,25 +842,25 @@ void XCHG_EDIEAX(void) { CPU_WORKCLOCK(3 INLINE static UINT32 BSWAP_DWORD(UINT32 val) { -#if defined(__GNUC__) && (defined(i386) || defined(__i386__)) +#if defined(GCC_CPU_ARCH_IA32) __asm__ __volatile__ ( -#if defined(IA32_USE_ASM_BSWAP) +#if defined(IA32_USE_ASM_BSWAP) || defined(GCC_CPU_ARCH_AMD64) "bswap %0" -#else /* !IA32_USE_ASM_BSWAP */ +#else /* !(IA32_USE_ASM_BSWAP || GCC_CPU_ARCH_AMD64) */ "rorw $8, %w1\n\t" "rorl $16, %1\n\t" "rorw $8, %w1\n\t" -#endif /* IA32_USE_ASM_BSWAP */ +#endif /* IA32_USE_ASM_BSWAP || GCC_CPU_ARCH_AMD64 */ : "=r" (val) : "0" (val)); return val; -#else /* !(__GNUC__ && (i386 || __i386__)) */ +#else /* !(__GNUC__ && GCC_CPU_ARCH_IA32) */ UINT32 v; v = (val & 0x000000ff) << 24; v |= (val & 0x0000ff00) << 8; v |= (val & 0x00ff0000) >> 8; v |= (val & 0xff000000) >> 24; return v; -#endif /* __GNUC__ && (i386 || __i386__) */ +#endif /* __GNUC__ && GCC_CPU_ARCH_IA32 */ } #endif /* bswap32 && !IA32_USE_ASM_BSWAP */ @@ -878,6 +876,33 @@ void BSWAP_EDI(void) { CPU_WORKCLOCK(2); /* * XADD */ +static UINT32 +XADD1(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + UINT32 res; + BYTE_ADD(res, dst, src); + return res; +} + +static UINT32 +XADD2(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + UINT32 res; + WORD_ADD(res, dst, src); + return res; +} + +static UINT32 +XADD4(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + UINT32 res; + DWORD_ADD(res, dst, src); + return res; +} + void XADD_EbGb(void) { @@ -889,16 +914,13 @@ XADD_EbGb(void) CPU_WORKCLOCK(2); out = reg8_b20[op]; dst = *out; - ADD_BYTE(res, dst, *src); + BYTE_ADD(res, dst, *src); *src = (UINT8)dst; *out = (UINT8)res; } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADD_BYTE(res, dst, *src); - *src = (UINT8)dst; - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); + *src = (UINT8)cpu_memory_access_va_RMW(CPU_INST_SEGREG_INDEX, madr, XADD1, UINT32_TO_PTR(*src)); } } @@ -913,16 +935,13 @@ XADD_EwGw(void) CPU_WORKCLOCK(2); out = reg16_b20[op]; dst = *out; - ADD_WORD(res, dst, *src); + WORD_ADD(res, dst, *src); *src = (UINT16)dst; *out = (UINT16)res; } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADD_WORD(res, dst, *src); - *src = (UINT16)dst; - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + *src = (UINT16)cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, XADD2, UINT32_TO_PTR(*src)); } } @@ -937,135 +956,46 @@ XADD_EdGd(void) CPU_WORKCLOCK(2); out = reg32_b20[op]; dst = *out; - ADD_DWORD(res, dst, *src); + DWORD_ADD(res, dst, *src); *src = dst; *out = res; } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADD_DWORD(res, dst, *src); - *src = dst; - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + *src = cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, XADD4, UINT32_TO_PTR(*src)); } } /* * CMPXCHG */ -#if 1 -void -CMPXCHG_EbGb(void) -{ - UINT8 *out; - UINT32 op, src, dst, madr, tmp; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - out = reg8_b20[op]; - dst = *out; - BYTE_SUB(tmp, CPU_AL, dst); - if (CPU_FLAGL & Z_FLAG) { - *out = (UINT8)src; - } else { - CPU_AL = (UINT8)dst; - } - } else { - madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SUB(tmp, CPU_AL, dst); - if (CPU_FLAGL & Z_FLAG) { - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)src); - } else { - CPU_AL = (UINT8)dst; - } - } -} - -void -CMPXCHG_EwGw(void) -{ - UINT16 *out; - UINT32 op, src, dst, madr, tmp; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - out = reg16_b20[op]; - dst = *out; - WORD_SUB(tmp, CPU_AX, dst); - if (CPU_FLAGL & Z_FLAG) { - *out = (UINT16)src; - } else { - CPU_AX = (UINT16)dst; - } - } else { - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SUB(tmp, CPU_AX, dst); - if (CPU_FLAGL & Z_FLAG) { - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); - } else { - CPU_AX = (UINT16)dst; - } - } -} - -void -CMPXCHG_EdGd(void) -{ - UINT32 *out; - UINT32 op, src, dst, madr, tmp; - - PREPART_EA_REG32(op, src); - if (op >= 0xc0) { - out = reg32_b20[op]; - dst = *out; - DWORD_SUB(tmp, CPU_EAX, dst); - if (CPU_FLAGL & Z_FLAG) { - *out = src; - } else { - CPU_EAX = dst; - } - } else { - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_SUB(tmp, CPU_EAX, dst); - if (CPU_FLAGL & Z_FLAG) { - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); - } else { - CPU_EAX = dst; - } - } -} -#else void CMPXCHG_EbGb(void) { UINT8 *out; UINT32 op, src, dst, madr, tmp; + UINT8 al; PREPART_EA_REG8(op, src); + al = CPU_AL; if (op >= 0xc0) { out = reg8_b20[op]; dst = *out; - if (CPU_AL == dst) { - CPU_FLAGL |= Z_FLAG; + if (al == dst) { *out = (UINT8)src; } else { - CPU_FLAGL &= ~Z_FLAG; CPU_AL = (UINT8)dst; } } else { madr = calc_ea_dst(op); dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - if (CPU_AL == dst) { - CPU_FLAGL |= Z_FLAG; + if (al == dst) { cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)src); } else { - CPU_FLAGL &= ~Z_FLAG; CPU_AL = (UINT8)dst; } } + BYTE_SUB(tmp, al, dst); } void @@ -1073,29 +1003,28 @@ CMPXCHG_EwGw(void) { UINT16 *out; UINT32 op, src, dst, madr, tmp; + UINT16 ax; PREPART_EA_REG16(op, src); + ax = CPU_AX; if (op >= 0xc0) { out = reg16_b20[op]; dst = *out; - if (CPU_AX == dst) { - CPU_FLAGL |= Z_FLAG; + if (ax == dst) { *out = (UINT16)src; } else { - CPU_FLAGL &= ~Z_FLAG; CPU_AX = (UINT16)dst; } } else { madr = calc_ea_dst(op); dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - if (CPU_AX == dst) { - CPU_FLAGL |= Z_FLAG; + if (ax == dst) { cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); } else { - CPU_FLAGL &= ~Z_FLAG; CPU_AX = (UINT16)dst; } } + WORD_SUB(tmp, ax, dst); } void @@ -1103,31 +1032,29 @@ CMPXCHG_EdGd(void) { UINT32 *out; UINT32 op, src, dst, madr, tmp; + UINT32 eax; PREPART_EA_REG32(op, src); + eax = CPU_EAX; if (op >= 0xc0) { out = reg32_b20[op]; dst = *out; - if (CPU_EAX == dst) { - CPU_FLAGL |= Z_FLAG; + if (eax == dst) { *out = src; } else { - CPU_FLAGL &= ~Z_FLAG; CPU_EAX = dst; } } else { madr = calc_ea_dst(op); dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - if (CPU_EAX == dst) { - CPU_FLAGL |= Z_FLAG; + if (eax == dst) { cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); } else { - CPU_FLAGL &= ~Z_FLAG; CPU_EAX = dst; } } + DWORD_SUB(tmp, eax, dst); } -#endif void CMPXCHG8B(UINT32 op)