--- np2/i386c/ia32/instructions/shift_rotate.mcr 2004/02/20 16:09:05 1.4 +++ np2/i386c/ia32/instructions/shift_rotate.mcr 2004/05/22 16:35:07 1.10 @@ -1,4 +1,4 @@ -/* $Id: shift_rotate.mcr,v 1.4 2004/02/20 16:09:05 monaka Exp $ */ +/* $Id: shift_rotate.mcr,v 1.10 2004/05/22 16:35:07 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -31,6 +31,283 @@ #define IA32_CPU_SHIFT_ROTATE_MCR__ /* + * shift/rorate instruction macro + */ +#define SHIFT_ROTATE_INSTRUCTION(inst) \ +static UINT32 \ +inst##1(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + (void)arg; \ + BYTE_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 \ +inst##2(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + (void)arg; \ + WORD_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 \ +inst##4(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + (void)arg; \ + DWORD_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 \ +inst##CL1(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + BYTE_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +static UINT32 \ +inst##CL2(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + WORD_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +static UINT32 \ +inst##CL4(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + DWORD_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +\ +void \ +inst##_Eb(UINT8 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + BYTE_##inst##1(dst, src); \ + *out = (UINT8)dst; \ +} \ +\ +void \ +inst##_Eb_ext(UINT32 madr) \ +{ \ +\ + cpu_memory_access_va_RMW(CPU_INST_SEGREG_INDEX, madr, inst##1, 0); \ +} \ +\ +void \ +inst##_Ew(UINT16 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + WORD_##inst##1(dst, src); \ + *out = (UINT16)dst; \ +} \ +\ +void \ +inst##_Ew_ext(UINT32 madr) \ +{ \ +\ + cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, 0); \ +} \ +\ +void \ +inst##_Ed(UINT32 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + DWORD_##inst##1(dst, src); \ + *out = dst; \ +} \ +\ +void \ +inst##_Ed_ext(UINT32 madr) \ +{ \ +\ + cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, 0); \ +} \ +\ +/* ExCL, ExIb */ \ +void \ +inst##_EbCL(UINT8 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + BYTE_##inst##CL(dst, src, cl); \ + *out = (UINT8)dst; \ +} \ +\ +void \ +inst##_EbCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_memory_access_va_RMW(CPU_INST_SEGREG_INDEX, madr, inst##CL1, (void *)cl); \ +} \ +\ +void \ +inst##_EwCL(UINT16 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + WORD_##inst##CL(dst, src, cl); \ + *out = (UINT16)dst; \ +} \ +\ +void \ +inst##_EwCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##CL2, (void *)cl); \ +} \ +\ +void \ +inst##_EdCL(UINT32 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + DWORD_##inst##CL(dst, src, cl); \ + *out = dst; \ +} \ +\ +void \ +inst##_EdCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##CL4, (void *)cl); \ +} + +/* + * shift double-words instructions + */ +struct SHxD_arg { + UINT32 src; + UINT32 cl; +}; + +#define SHxD_INSTRUCTION(inst) \ +static UINT32 \ +inst##2(UINT32 dst, void *arg) \ +{ \ + struct SHxD_arg *p = (struct SHxD_arg *)arg; \ + UINT32 src = p->src; \ + UINT32 cl = p->cl; \ + WORD_##inst(dst, src, cl); \ + return dst; \ +} \ +static UINT32 \ +inst##4(UINT32 dst, void *arg) \ +{ \ + struct SHxD_arg *p = (struct SHxD_arg *)arg; \ + UINT32 src = p->src; \ + UINT32 cl = p->cl; \ + DWORD_##inst(dst, src, cl); \ + return dst; \ +} \ +\ +void \ +inst##_EwGwIb(void) \ +{ \ + struct SHxD_arg arg; \ + UINT16 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG16(op, arg.src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + GET_PCBYTE(arg.cl); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(dst, arg.src, arg.cl); \ + *out = (UINT16)dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + GET_PCBYTE(arg.cl); \ + cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, &arg); \ + } \ +} \ +\ +void \ +inst##_EdGdIb(void) \ +{ \ + struct SHxD_arg arg; \ + UINT32 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG32(op, arg.src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + GET_PCBYTE(arg.cl); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(dst, arg.src, arg.cl); \ + *out = dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + GET_PCBYTE(arg.cl); \ + cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, &arg); \ + } \ +} \ +\ +void \ +inst##_EwGwCL(void) \ +{ \ + struct SHxD_arg arg; \ + UINT16 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG16(op, arg.src); \ + arg.cl = CPU_CL; \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(dst, arg.src, arg.cl); \ + *out = (UINT16)dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, (void *)&arg); \ + } \ +} \ +\ +void \ +inst##_EdGdCL(void) \ +{ \ + struct SHxD_arg arg; \ + UINT32 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG32(op, arg.src); \ + arg.cl = CPU_CL; \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(dst, arg.src, arg.cl); \ + *out = dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, (void *)&arg); \ + } \ +} + + +/* Pentium!!! - シフトカウント != 1の場合はOVは不変らすい */ + +/* * SAR */ #define _BYTE_SAR1(d, s) \ @@ -54,8 +331,7 @@ do { \ CPU_FLAGL = (UINT8)(A_FLAG | ((s) & 1)); /* C_FLAG */ \ if ((d) == 0) { \ CPU_FLAGL |= Z_FLAG; \ - } \ - if ((d) & 0x80000000) { \ + } else if ((d) & 0x80000000) { \ CPU_FLAGL |= S_FLAG; \ } \ CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ @@ -64,11 +340,15 @@ do { \ #define _BYTE_SARCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - (s) = ((SINT8)(s)) >> ((c) - 1); \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) = ((SINT8)(s)) >> (c); \ + } else { \ + CPU_OV = 0; \ + } \ CPU_FLAGL = (UINT8)((s) & 1); /* C_FLAG */ \ (s) = (UINT8)(((SINT8)(s)) >> 1); \ - CPU_OV = 0; \ CPU_FLAGL |= (szpcflag[(UINT8)(s)] | A_FLAG); \ } \ (d) = (s); \ @@ -77,11 +357,15 @@ do { \ #define _WORD_SARCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - (s) = ((SINT16)(s)) >> ((c) - 1); \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) = ((SINT16)(s)) >> (c); \ + } else { \ + CPU_OV = 0; \ + } \ CPU_FLAGL = (UINT8)((s) & 1); /* C_FLAG */ \ (s) = (UINT16)(((SINT16)(s)) >> 1); \ - CPU_OV = 0; \ CPU_FLAGL |= szpflag_w[(UINT16)(s)]; \ } \ (d) = (s); \ @@ -91,14 +375,17 @@ do { \ do { \ (c) &= 0x1f; \ if ((c)) { \ - (s) = ((SINT32)(s)) >> ((c) - 1); \ + (c)--; \ + if ((c)) { \ + (s) = ((SINT32)(s)) >> (c); \ + } else { \ + CPU_OV = 0; \ + } \ CPU_FLAGL = (UINT8)((s) & 1); /* C_FLAG */ \ (s) = (UINT32)(((SINT32)(s)) >> 1); \ - CPU_OV = 0; \ if ((s) == 0) { \ CPU_FLAGL |= Z_FLAG; \ - } \ - if ((s) & 0x80000000) { \ + } else if ((s) & 0x80000000) { \ CPU_FLAGL |= S_FLAG; \ } \ CPU_FLAGL |= (szpcflag[(UINT8)(s)] & P_FLAG); \ @@ -137,15 +424,15 @@ do { \ #define _BYTE_SHRCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - if ((c) >= 0x10) { \ - (c) &= 7; \ - (c) |= 8; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) >>= (c); \ + } else { \ + CPU_OV = (s) & 0x80; \ } \ - (s) >>= (c) - 1; \ CPU_FLAGL = (UINT8)((s) & 1); \ (s) >>= 1; \ - CPU_OV = ((s) ^ ((s) >> 1)) & 0x40; \ CPU_FLAGL |= (szpcflag[(UINT8)(s)] | A_FLAG); \ } \ (d) = (s); \ @@ -154,11 +441,10 @@ do { \ #define _WORD_SHRCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ + if ((c)) { \ (c)--; \ - if (c) { \ + if ((c)) { \ (s) >>= (c); \ - CPU_OV = 0; \ } else { \ CPU_OV = (s) & 0x8000; \ } \ @@ -172,11 +458,10 @@ do { \ #define _DWORD_SHRCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ + if ((c)) { \ (c)--; \ - if (c) { \ + if ((c)) { \ (s) >>= (c); \ - CPU_OV = 0; \ } else { \ CPU_OV = (s) & 0x80000000; \ } \ @@ -217,8 +502,7 @@ do { \ } \ if ((d) == 0) { \ CPU_FLAGL |= Z_FLAG; \ - } \ - if ((d) & 0x80000000) { \ + } else if ((d) & 0x80000000) { \ CPU_FLAGL |= S_FLAG; \ } \ } while (/*CONSTCOND*/ 0) @@ -226,15 +510,13 @@ do { \ #define _BYTE_SHLCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - if ((c) >= 0x10) { \ - (c) &= 7; \ - (c) |= 8; \ + if ((c)) { \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x40) & 0x80; \ } \ (s) <<= (c); \ (s) &= 0x1ff; \ CPU_FLAGL = (UINT8)(szpcflag[(s) & 0x1ff] | A_FLAG); \ - CPU_OV = ((s) ^ ((s) >> 1)) & 0x80; \ } \ (d) = (s); \ } while (/*CONSTCOND*/ 0) @@ -242,8 +524,7 @@ do { \ #define _WORD_SHLCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - CPU_OV = 0; \ + if ((c)) { \ if ((c) == 1) { \ CPU_OV = ((s) + 0x4000) & 0x8000; \ } \ @@ -258,11 +539,10 @@ do { \ #define _DWORD_SHLCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ + if ((c)) { \ (c)--; \ if ((c)) { \ (s) <<= (c); \ - CPU_OV = 0; \ } else { \ CPU_OV = ((s) + 0x40000000) & 0x80000000; \ } \ @@ -273,8 +553,7 @@ do { \ (s) <<= 1; \ if ((s) == 0) { \ CPU_FLAGL |= Z_FLAG; \ - } \ - if ((s) & 0x80000000) { \ + } else if ((s) & 0x80000000) { \ CPU_FLAGL |= S_FLAG; \ } \ CPU_FLAGL |= (szpcflag[(UINT8)(s)] & P_FLAG); \ @@ -288,15 +567,16 @@ do { \ #define _WORD_SHRD(d, s, c) \ do { \ (c) &= 0x1f; \ - if ((c)) { \ - if ((c) < 16) { \ - CPU_FLAGL = (UINT8)(((d) >> ((c) - 1)) & 1); /*C_FLAG*/ \ - (d) |= (s) << 16; \ - (d) >>= (c); \ - (d) &= 0xffff; \ - CPU_FLAGL |= szpflag_w[(UINT16)(d)] | A_FLAG; \ - CPU_OV = (d) & 0x8000; \ + if (((c)) && ((c) < 16)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = (((d) >> 15) ^ (s)) & 1; \ } \ + CPU_FLAGL = (UINT8)(((d) >> ((c) - 1)) & 1); /*C_FLAG*/ \ + (d) |= (s) << 16; \ + (d) >>= (c); \ + (d) &= 0xffff; \ + CPU_FLAGL |= szpflag_w[(UINT16)(d)] | A_FLAG; \ } \ } while (/*CONSTCOND*/ 0) @@ -304,17 +584,19 @@ do { \ do { \ (c) &= 0x1f; \ if ((c)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = (((d) >> 31) ^ (s)) & 1; \ + } \ CPU_FLAGL = (UINT8)(((d) >> ((c) - 1)) & 1); /* C_FLAG */ \ (d) >>= (c); \ (d) |= (s) << (32 - (c)); \ if ((d) == 0) { \ CPU_FLAGL |= Z_FLAG; \ - } \ - if ((d) & 0x80000000) { \ + } else if ((d) & 0x80000000) { \ CPU_FLAGL |= S_FLAG; \ } \ CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ - CPU_OV = (d) & 0x80000000; \ } \ } while (/*CONSTCOND*/ 0) @@ -324,15 +606,16 @@ do { \ #define _WORD_SHLD(d, s, c) \ do { \ (c) &= 0x1f; \ - if ((c)) { \ - if ((c) < 16) { \ - CPU_FLAGL = (UINT8)(((d) >> (16 - (c))) & 1); /*C_FLAG*/\ - (d) = ((d) << 16) | (s); \ - (d) <<= (c); \ - (d) >>= 16; \ - CPU_FLAGL |= szpflag_w[(d)] | A_FLAG; \ - CPU_OV = (d) & 0x8000; \ + if (((c)) && ((c) < 16)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((d) ^ ((d) << 1)) & 0x8000; \ } \ + CPU_FLAGL = (UINT8)(((d) >> (16 - (c))) & 1); /*C_FLAG*/\ + (d) = ((d) << 16) | (s); \ + (d) <<= (c); \ + (d) >>= 16; \ + CPU_FLAGL |= szpflag_w[(d)] | A_FLAG; \ } \ } while (/*CONSTCOND*/ 0) @@ -340,17 +623,19 @@ do { \ do { \ (c) &= 0x1f; \ if ((c)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((d) ^ ((d) << 1)) & 0x80000000; \ + } \ CPU_FLAGL = (UINT8)(((d) >> (32 - (c))) & 1); /* C_FLAG */ \ (d) <<= (c); \ (d) |= ((s) >> (32 - (c))); \ if ((d) == 0) { \ CPU_FLAGL |= Z_FLAG; \ - } \ - if ((d) & 0x80000000) { \ + } else if ((d) & 0x80000000) { \ CPU_FLAGL |= S_FLAG; \ } \ CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ - CPU_OV = (d) & 0x80000000; \ } \ } while (/*CONSTCOND*/ 0) @@ -693,7 +978,7 @@ do { \ (d) = (s); \ } while (/*CONSTCOND*/ 0) -#if defined(IA32_CROSS_CHECK) && defined(__GNUC__) && (defined(i386) || defined(i386)) +#if defined(IA32_CROSS_CHECK) && defined(GCC_CPU_ARCH_IA32) #include "shift_rotatexc.mcr" @@ -744,7 +1029,11 @@ do { \ #define WORD_RCLCL(d, s, c) XC_WORD_RCLCL(d, s, c) #define DWORD_RCLCL(d, s, c) XC_DWORD_RCLCL(d, s, c) -#else /* !(IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__)) */ +#elif defined(IA32_CROSS_CHECK) && defined(_MSC_VER) + +#include "shift_rotatexc_msc.mcr" + +#else /* !(IA32_CROSS_CHECK && GCC_CPU_ARCH_IA32 */ #define BYTE_SAR1(d, s) _BYTE_SAR1(d, s) #define WORD_SAR1(d, s) _WORD_SAR1(d, s) @@ -793,6 +1082,6 @@ do { \ #define WORD_RCLCL(d, s, c) _WORD_RCLCL(d, s, c) #define DWORD_RCLCL(d, s, c) _DWORD_RCLCL(d, s, c) -#endif /* IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__) */ +#endif /* IA32_CROSS_CHECK && GCC_CPU_ARCH_IA32 */ #endif /* IA32_CPU_SHIFT_ROTATE_MCR__ */