--- np2/i386c/ia32/instructions/shift_rotate.mcr 2004/03/10 23:01:08 1.8 +++ np2/i386c/ia32/instructions/shift_rotate.mcr 2012/01/23 03:52:54 1.18 @@ -1,5 +1,3 @@ -/* $Id: shift_rotate.mcr,v 1.8 2004/03/10 23:01:08 yui Exp $ */ - /* * Copyright (c) 2003 NONAKA Kimihiro * All rights reserved. @@ -12,8 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -30,7 +26,279 @@ #ifndef IA32_CPU_SHIFT_ROTATE_MCR__ #define IA32_CPU_SHIFT_ROTATE_MCR__ -/* Pentium!!! - シフトカウント != 1の場合はOVは不変らすい */ +/* + * shift/rorate instruction macro + */ +#define SHIFT_ROTATE_INSTRUCTION(inst) \ +static UINT32 CPUCALL \ +inst##1(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + BYTE_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##2(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + WORD_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##4(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + DWORD_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##CL1(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + BYTE_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##CL2(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + WORD_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##CL4(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + DWORD_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +\ +void CPUCALL \ +inst##_Eb(UINT8 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + BYTE_##inst##1(dst, src); \ + *out = (UINT8)dst; \ +} \ +\ +void CPUCALL \ +inst##_Eb_ext(UINT32 madr) \ +{ \ +\ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, 0); \ +} \ +\ +void CPUCALL \ +inst##_Ew(UINT16 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + WORD_##inst##1(dst, src); \ + *out = (UINT16)dst; \ +} \ +\ +void CPUCALL \ +inst##_Ew_ext(UINT32 madr) \ +{ \ +\ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, 0); \ +} \ +\ +void CPUCALL \ +inst##_Ed(UINT32 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + DWORD_##inst##1(dst, src); \ + *out = dst; \ +} \ +\ +void CPUCALL \ +inst##_Ed_ext(UINT32 madr) \ +{ \ +\ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, 0); \ +} \ +\ +/* ExCL, ExIb */ \ +void CPUCALL \ +inst##_EbCL(UINT8 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + BYTE_##inst##CL(dst, src, cl); \ + *out = (UINT8)dst; \ +} \ +\ +void CPUCALL \ +inst##_EbCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##CL1, UINT32_TO_PTR(cl)); \ +} \ +\ +void CPUCALL \ +inst##_EwCL(UINT16 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + WORD_##inst##CL(dst, src, cl); \ + *out = (UINT16)dst; \ +} \ +\ +void CPUCALL \ +inst##_EwCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##CL2, UINT32_TO_PTR(cl)); \ +} \ +\ +void CPUCALL \ +inst##_EdCL(UINT32 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + DWORD_##inst##CL(dst, src, cl); \ + *out = dst; \ +} \ +\ +void CPUCALL \ +inst##_EdCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##CL4, UINT32_TO_PTR(cl)); \ +} + +/* + * shift double-words instructions + */ +struct SHxD_arg { + UINT32 src; + UINT32 cl; +}; + +#define SHxD_INSTRUCTION(inst) \ +static UINT32 CPUCALL \ +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 CPUCALL \ +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_vmemory_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_vmemory_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_vmemory_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_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, (void *)&arg); \ + } \ +} + + +/* Pentium!!! - シフトカウント != 1の場合はOVは不変らすい */ /* * SAR @@ -613,8 +881,9 @@ do { \ CPU_OV = ((s) >> 31) ^ tmp; \ } \ while ((c)--) { \ - tmp = (s) & 1; \ + UINT32 tmp2 = (s) & 1; \ (s) = (tmp << 31) | ((s) >> 1); \ + tmp = tmp2; \ } \ CPU_FLAGL |= tmp; \ } \ @@ -694,16 +963,16 @@ do { \ CPU_OV = ((s) + 0x40000000) & 0x80000000; \ } \ while ((c)--) { \ - tmp = (s) & 0x80000000; \ + UINT32 tmp2 = (s) & 0x80000000; \ (s) = ((s) << 1) | (tmp & 1); \ - tmp >>= 31; \ + tmp = tmp2 >> 31; \ } \ CPU_FLAGL |= tmp; \ } \ (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" @@ -758,7 +1027,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) @@ -807,6 +1076,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__ */