--- np2/i386c/ia32/instructions/shift_rotate.mcr 2004/03/10 15:38:51 1.7 +++ 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.7 2004/03/10 15:38:51 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,10 +375,14 @@ 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; \ } else if ((s) & 0x80000000) { \ @@ -136,15 +424,11 @@ do { \ #define _BYTE_SHRCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - if ((c) >= 0x10) { \ - (c) = 10; \ - } \ + if ((c)) { \ (c)--; \ - if (c) { \ + if ((c)) { \ (s) >>= (c); \ - } \ - else { \ + } else { \ CPU_OV = (s) & 0x80; \ } \ CPU_FLAGL = (UINT8)((s) & 1); \ @@ -157,9 +441,9 @@ do { \ #define _WORD_SHRCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ + if ((c)) { \ (c)--; \ - if (c) { \ + if ((c)) { \ (s) >>= (c); \ } else { \ CPU_OV = (s) & 0x8000; \ @@ -174,9 +458,9 @@ do { \ #define _DWORD_SHRCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ + if ((c)) { \ (c)--; \ - if (c) { \ + if ((c)) { \ (s) >>= (c); \ } else { \ CPU_OV = (s) & 0x80000000; \ @@ -226,10 +510,7 @@ do { \ #define _BYTE_SHLCL(d, s, c) \ do { \ (c) &= 0x1f; \ - if (c) { \ - if ((c) > 0x10) { \ - (c) = 10; \ - } \ + if ((c)) { \ if ((c) == 1) { \ CPU_OV = ((s) + 0x40) & 0x80; \ } \ @@ -243,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; \ } \ @@ -259,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; \ } \ @@ -274,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); \ @@ -315,8 +593,7 @@ do { \ (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); \ @@ -355,8 +632,7 @@ do { \ (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); \ @@ -702,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" @@ -757,7 +1033,7 @@ do { \ #include "shift_rotatexc_msc.mcr" -#else /* !(IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__)) */ +#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) @@ -806,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__ */