--- np2/i386c/ia32/instructions/bin_arith.c 2003/12/11 15:06:50 1.2 +++ np2/i386c/ia32/instructions/bin_arith.c 2004/03/23 15:29:34 1.10 @@ -1,7 +1,7 @@ -/* $Id: bin_arith.c,v 1.2 2003/12/11 15:06:50 monaka Exp $ */ +/* $Id: bin_arith.c,v 1.10 2004/03/23 15:29:34 monaka Exp $ */ /* - * Copyright (c) 2002-2003 NONAKA Kimihiro + * Copyright (c) 2002-2004 NONAKA Kimihiro * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,827 +30,29 @@ #include "compiler.h" #include "cpu.h" #include "ia32.mcr" +#include "arith.mcr" #include "bin_arith.h" /* - * ADD + * arith */ -void -ADD_EbGb(void) -{ - BYTE *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - dst = *out; - ADDBYTE(res, dst, src); - *out = (BYTE)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADDBYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); - } -} - -void -ADD_EwGw(void) -{ - WORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - dst = *out; - ADDWORD(res, dst, src); - *out = (WORD)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADDWORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); - } -} - -void -ADD_EdGd(void) -{ - DWORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG32(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - dst = *out; - ADDDWORD(res, dst, src); - *out = res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADDDWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); - } -} - -void -ADD_GbEb(void) -{ - BYTE *out; - DWORD op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - ADDBYTE(res, dst, src); - *out = (BYTE)res; -} - -void -ADD_GwEw(void) -{ - WORD *out; - DWORD op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - ADDWORD(res, dst, src); - *out = (WORD)res; -} - -void -ADD_GdEd(void) -{ - DWORD *out; - DWORD op, src, dst, res; - - PREPART_REG32_EA(op, src, out, 2, 7); - dst = *out; - ADDDWORD(res, dst, src); - *out = (DWORD)res; -} - -void -ADD_ALIb(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCBYTE(src); - dst = CPU_AL; - ADDBYTE(res, dst, src); - CPU_AL = (BYTE)res; -} - -void -ADD_AXIw(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCWORD(src); - dst = CPU_AX; - ADDWORD(res, dst, src); - CPU_AX = (WORD)res; -} - -void -ADD_EAXId(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCDWORD(src); - dst = CPU_EAX; - ADDDWORD(res, dst, src); - CPU_EAX = res; -} - -void -ADD_EbIb(BYTE *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - ADDBYTE(res, dst, src); - *regp = (BYTE)res; -} - -void -ADD_EbIb_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADDBYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); -} - -void -ADD_EwIx(WORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - ADDWORD(res, dst, src); - *regp = (WORD)res; -} - -void -ADD_EwIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADDWORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); -} - -void -ADD_EdIx(DWORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - ADDDWORD(res, dst, src); - *regp = res; -} - -void -ADD_EdIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADDDWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); -} - - -/* - * ADC - */ -void -ADC_EbGb(void) -{ - BYTE *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - dst = *out; - ADCBYTE(res, dst, src); - *out = (BYTE)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADCBYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); - } -} - -void -ADC_EwGw(void) -{ - WORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - dst = *out; - ADCWORD(res, dst, src); - *out = (WORD)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADCWORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); - } -} - -void -ADC_EdGd(void) -{ - DWORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - dst = *out; - ADCDWORD(res, dst, src); - *out = res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADCDWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, (WORD)res); - } -} - -void -ADC_GbEb(void) -{ - BYTE *out; - DWORD op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - ADCBYTE(res, dst, src); - *out = (BYTE)res; -} - -void -ADC_GwEw(void) -{ - WORD *out; - DWORD op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - ADCWORD(res, dst, src); - *out = (WORD)res; -} - -void -ADC_GdEd(void) -{ - DWORD *out; - DWORD op, src, dst, res; - - PREPART_REG32_EA(op, src, out, 2, 7); - dst = *out; - ADCDWORD(res, dst, src); - *out = res; -} - -void -ADC_ALIb(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCBYTE(src); - dst = CPU_AL; - ADCBYTE(res, dst, src); - CPU_AL = (BYTE)res; -} - -void -ADC_AXIw(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCWORD(src); - dst = CPU_AX; - ADCWORD(res, dst, src); - CPU_AX = (WORD)res; -} - -void -ADC_EAXId(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCDWORD(src); - dst = CPU_EAX; - ADCDWORD(res, dst, src); - CPU_EAX = res; -} - -void -ADC_EbIb(BYTE *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - ADCBYTE(res, dst, src); - *regp = (BYTE)res; -} - -void -ADC_EbIb_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADCBYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); -} - -void -ADC_EwIx(WORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - ADCWORD(res, dst, src); - *regp = (WORD)res; -} - -void -ADC_EwIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADCWORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); -} - -void -ADC_EdIx(DWORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - ADCDWORD(res, dst, src); - *regp = res; -} - -void -ADC_EdIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADCDWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); -} - - -/* - * SUB - */ -void -SUB_EbGb(void) -{ - BYTE *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - dst = *out; - BYTE_SUB(res, dst, src); - *out = (BYTE)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SUB(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); - } -} - -void -SUB_EwGw(void) -{ - WORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - dst = *out; - WORD_SUB(res, dst, src); - *out = (WORD)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SUB(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); - } -} - -void -SUB_EdGd(void) -{ - DWORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG32(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - dst = *out; - DWORD_SUB(res, dst, src); - *out = res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_SUB(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); - } -} - -void -SUB_GbEb(void) -{ - BYTE *out; - DWORD op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - BYTE_SUB(res, dst, src); - *out = (BYTE)res; -} - -void -SUB_GwEw(void) -{ - WORD *out; - DWORD op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - WORD_SUB(res, dst, src); - *out = (WORD)res; -} - -void -SUB_GdEd(void) -{ - DWORD *out; - DWORD op, src, dst, res; - - PREPART_REG32_EA(op, src, out, 2, 7); - dst = *out; - DWORD_SUB(res, dst, src); - *out = res; -} - -void -SUB_ALIb(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCBYTE(src); - dst = CPU_AL; - BYTE_SUB(res, dst, src); - CPU_AL = (BYTE)res; -} - -void -SUB_AXIw(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCWORD(src); - dst = CPU_AX; - WORD_SUB(res, dst, src); - CPU_AX = (WORD)res; -} - -void -SUB_EAXId(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCDWORD(src); - dst = CPU_EAX; - DWORD_SUB(res, dst, src); - CPU_EAX = res; -} - -void -SUB_EbIb(BYTE *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - BYTE_SUB(res, dst, src); - *regp = (BYTE)res; -} - -void -SUB_EbIb_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SUB(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); -} - -void -SUB_EwIx(WORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - WORD_SUB(res, dst, src); - *regp = (WORD)res; -} - -void -SUB_EwIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SUB(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); -} - -void -SUB_EdIx(DWORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - DWORD_SUB(res, dst, src); - *regp = res; -} - -void -SUB_EdIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_SUB(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); -} - - -/* - * SBB - */ -void -SBB_EbGb(void) -{ - BYTE *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - dst = *out; - BYTE_SBB(res, dst, src); - *out = (BYTE)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SBB(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); - } -} - -void -SBB_EwGw(void) -{ - WORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - dst = *out; - WORD_SBB(res, dst, src); - *out = (WORD)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SBB(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); - } -} - -void -SBB_EdGd(void) -{ - DWORD *out; - DWORD op, src, dst, res, madr; - - PREPART_EA_REG32(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - dst = *out; - DWORD_SBB(res, dst, src); - *out = res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_SBB(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); - } -} - -void -SBB_GbEb(void) -{ - BYTE *out; - DWORD op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - BYTE_SBB(res, dst, src); - *out = (BYTE)res; -} - -void -SBB_GwEw(void) -{ - WORD *out; - DWORD op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - WORD_SBB(res, dst, src); - *out = (WORD)res; -} - -void -SBB_GdEd(void) -{ - DWORD *out; - DWORD op, src, dst, res; - - PREPART_REG32_EA(op, src, out, 2, 7); - dst = *out; - DWORD_SBB(res, dst, src); - *out = res; -} - -void -SBB_ALIb(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCBYTE(src); - dst = CPU_AL; - BYTE_SBB(res, dst, src); - CPU_AL = (BYTE)res; -} - -void -SBB_AXIw(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCWORD(src); - dst = CPU_AX; - WORD_SBB(res, dst, src); - CPU_AX = (WORD)res; -} - -void -SBB_EAXId(void) -{ - DWORD src, dst, res; - - CPU_WORKCLOCK(3); - GET_PCDWORD(src); - dst = CPU_EAX; - DWORD_SBB(res, dst, src); - CPU_EAX = res; -} - -void -SBB_EbIb(BYTE *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - BYTE_SBB(res, dst, src); - *regp = (BYTE)res; -} - -void -SBB_EbIb_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SBB(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)res); -} - -void -SBB_EwIx(WORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - WORD_SBB(res, dst, src); - *regp = (WORD)res; -} - -void -SBB_EwIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SBB(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)res); -} - -void -SBB_EdIx(DWORD *regp, DWORD src) -{ - DWORD dst, res; - - dst = *regp; - DWORD_SBB(res, dst, src); - *regp = res; -} - -void -SBB_EdIx_ext(DWORD madr, DWORD src) -{ - DWORD dst, res; - - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_SBB(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); -} +ARITH_INSTRUCTION_3(ADD) +ARITH_INSTRUCTION_3(ADC) +ARITH_INSTRUCTION_3(SUB) +ARITH_INSTRUCTION_3(SBB) /* * IMUL */ void -IMUL_ALEb(DWORD op) +IMUL_ALEb(UINT32 op) { - DWORD madr; - SDWORD res; - SBYTE src, dst; + UINT32 madr; + SINT32 res; + SINT8 src, dst; if (op >= 0xc0) { CPU_WORKCLOCK(13); @@ -862,15 +64,15 @@ IMUL_ALEb(DWORD op) } dst = CPU_AL; BYTE_IMUL(res, dst, src); - CPU_AX = (WORD)res; + CPU_AX = (UINT16)res; } void -IMUL_AXEw(DWORD op) +IMUL_AXEw(UINT32 op) { - DWORD madr; - SDWORD res; - SWORD src, dst; + UINT32 madr; + SINT32 res; + SINT16 src, dst; if (op >= 0xc0) { CPU_WORKCLOCK(21); @@ -882,16 +84,16 @@ IMUL_AXEw(DWORD op) } dst = CPU_AX; WORD_IMUL(res, dst, src); - CPU_AX = (WORD)(res & 0xffff); - CPU_DX = (WORD)(res >> 16); + CPU_AX = (UINT16)(res & 0xffff); + CPU_DX = (UINT16)(res >> 16); } void -IMUL_EAXEd(DWORD op) +IMUL_EAXEd(UINT32 op) { - DWORD madr; - SQWORD res; - SDWORD src, dst; + UINT32 madr; + SINT64 res; + SINT32 src, dst; if (op >= 0xc0) { CPU_WORKCLOCK(21); @@ -903,92 +105,92 @@ IMUL_EAXEd(DWORD op) } dst = CPU_EAX; DWORD_IMUL(res, dst, src); - CPU_EAX = (DWORD)res; - CPU_EDX = (DWORD)(res >> 32); + CPU_EAX = (UINT32)res; + CPU_EDX = (UINT32)(res >> 32); } void IMUL_GwEw(void) { - WORD *out; - DWORD op; - SDWORD res; - SWORD src, dst; + UINT16 *out; + UINT32 op; + SINT32 res; + SINT16 src, dst; PREPART_REG16_EA(op, src, out, 21, 27); dst = *out; WORD_IMUL(res, dst, src); - *out = (WORD)res; + *out = (UINT16)res; } void IMUL_GdEd(void) { - DWORD *out; - DWORD op; - SQWORD res; - SDWORD src, dst; + UINT32 *out; + UINT32 op; + SINT64 res; + SINT32 src, dst; PREPART_REG32_EA(op, src, out, 21, 27); dst = *out; DWORD_IMUL(res, dst, src); - *out = (DWORD)res; + *out = (UINT32)res; } void IMUL_GwEwIb(void) { - WORD *out; - DWORD op; - SDWORD res; - SWORD src, dst; + UINT16 *out; + UINT32 op; + SINT32 res; + SINT16 src, dst; PREPART_REG16_EA(op, src, out, 21, 24); GET_PCBYTES(dst); WORD_IMUL(res, dst, src); - *out = (WORD)res; + *out = (UINT16)res; } void IMUL_GdEdIb(void) { - DWORD *out; - DWORD op; - SQWORD res; - SDWORD src, dst; + UINT32 *out; + UINT32 op; + SINT64 res; + SINT32 src, dst; PREPART_REG32_EA(op, src, out, 21, 24); GET_PCBYTESD(dst); DWORD_IMUL(res, dst, src); - *out = (DWORD)res; + *out = (UINT32)res; } void IMUL_GwEwIw(void) { - WORD *out; - DWORD op; - SDWORD res; - SWORD src, dst; + UINT16 *out; + UINT32 op; + SINT32 res; + SINT16 src, dst; PREPART_REG16_EA(op, src, out, 21, 24); GET_PCWORD(dst); WORD_IMUL(res, dst, src); - *out = (WORD)res; + *out = (UINT16)res; } void IMUL_GdEdId(void) { - DWORD *out; - DWORD op; - SQWORD res; - SDWORD src, dst; + UINT32 *out; + UINT32 op; + SINT64 res; + SINT32 src, dst; PREPART_REG32_EA(op, src, out, 21, 24); GET_PCDWORD(dst); DWORD_IMUL(res, dst, src); - *out = res; + *out = (UINT32)res; } @@ -996,10 +198,10 @@ IMUL_GdEdId(void) * MUL */ void -MUL_ALEb(DWORD op) +MUL_ALEb(UINT32 op) { - DWORD res, madr; - BYTE src, dst; + UINT32 res, madr; + UINT8 src, dst; if (op >= 0xc0) { CPU_WORKCLOCK(13); @@ -1011,14 +213,14 @@ MUL_ALEb(DWORD op) } dst = CPU_AL; BYTE_MUL(res, dst, src); - CPU_AX = (WORD)res; + CPU_AX = (UINT16)res; } void -MUL_AXEw(DWORD op) +MUL_AXEw(UINT32 op) { - DWORD res, madr; - WORD src, dst; + UINT32 res, madr; + UINT16 src, dst; if (op >= 0xc0) { CPU_WORKCLOCK(21); @@ -1030,15 +232,15 @@ MUL_AXEw(DWORD op) } dst = CPU_AX; WORD_MUL(res, dst, src); - CPU_AX = (WORD)res; - CPU_DX = (WORD)(res >> 16); + CPU_AX = (UINT16)res; + CPU_DX = (UINT16)(res >> 16); } void -MUL_EAXEd(DWORD op) +MUL_EAXEd(UINT32 op) { - DWORD res, madr; - DWORD src, dst; + UINT32 res, madr; + UINT32 src, dst; if (op >= 0xc0) { CPU_WORKCLOCK(21); @@ -1059,11 +261,11 @@ MUL_EAXEd(DWORD op) * IDIV */ void -IDIV_ALEb(DWORD op) +IDIV_ALEb(UINT32 op) { - DWORD madr; - SWORD tmp, r; - SBYTE src; + UINT32 madr; + SINT16 tmp, r; + SINT8 src; if (op >= 0xc0) { CPU_WORKCLOCK(17); @@ -1073,11 +275,11 @@ IDIV_ALEb(DWORD op) madr = calc_ea_dst(op); src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); } - tmp = (SWORD)CPU_AX; + tmp = (SINT16)CPU_AX; if (src != 0) { r = tmp / src; if (((r + 0x80) & 0xff00) == 0) { - CPU_AL = (SBYTE)r; + CPU_AL = (SINT8)r; CPU_AH = tmp % src; return; } @@ -1086,11 +288,11 @@ IDIV_ALEb(DWORD op) } void -IDIV_AXEw(DWORD op) +IDIV_AXEw(UINT32 op) { - SDWORD tmp, r; - DWORD madr; - SWORD src; + SINT32 tmp, r; + UINT32 madr; + SINT16 src; if (op >= 0xc0) { CPU_WORKCLOCK(17); @@ -1100,11 +302,11 @@ IDIV_AXEw(DWORD op) madr = calc_ea_dst(op); src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } - tmp = (SDWORD)(((DWORD)CPU_DX << 16) + CPU_AX); + tmp = (SINT32)(((UINT32)CPU_DX << 16) + (UINT32)CPU_AX); if (src != 0) { r = tmp / src; if (((r + 0x8000) & 0xffff0000) == 0) { - CPU_AX = (SWORD)r; + CPU_AX = (SINT16)r; CPU_DX = tmp % src; return; } @@ -1113,11 +315,11 @@ IDIV_AXEw(DWORD op) } void -IDIV_EAXEd(DWORD op) +IDIV_EAXEd(UINT32 op) { - SQWORD tmp, r; - SDWORD src; - DWORD madr; + SINT64 tmp, r; + SINT32 src; + UINT32 madr; if (op >= 0xc0) { CPU_WORKCLOCK(17); @@ -1127,12 +329,12 @@ IDIV_EAXEd(DWORD op) madr = calc_ea_dst(op); src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); } - tmp = (SQWORD)(((QWORD)CPU_EDX << 32) + CPU_EAX); + tmp = (SINT64)(((UINT64)CPU_EDX << 32) + (SINT64)CPU_EAX); if (src != 0) { r = tmp / src; - if (((r + 0x80000000) & 0xffffffff00000000ULL) == 0) { - CPU_EAX = (SDWORD)r; - CPU_EDX = tmp % src; + if (((r + SQWORD_CONST(0x80000000)) & QWORD_CONST(0xffffffff00000000)) == 0) { + CPU_EAX = (SINT32)r; + CPU_EDX = (SINT32)(tmp % src); return; } } @@ -1144,11 +346,11 @@ IDIV_EAXEd(DWORD op) * DIV */ void -DIV_ALEb(DWORD op) +DIV_ALEb(UINT32 op) { - DWORD madr; - WORD tmp; - BYTE src; + UINT32 madr; + UINT16 tmp; + UINT8 src; if (op >= 0xc0) { CPU_WORKCLOCK(17); @@ -1160,7 +362,7 @@ DIV_ALEb(DWORD op) } tmp = CPU_AX; if (src != 0) { - if (tmp < ((WORD)src << 8)) { + if (tmp < ((UINT16)src << 8)) { CPU_AL = tmp / src; CPU_AH = tmp % src; return; @@ -1170,11 +372,11 @@ DIV_ALEb(DWORD op) } void -DIV_AXEw(DWORD op) +DIV_AXEw(UINT32 op) { - DWORD madr; - DWORD tmp; - WORD src; + UINT32 madr; + UINT32 tmp; + UINT16 src; if (op >= 0xc0) { CPU_WORKCLOCK(17); @@ -1184,11 +386,11 @@ DIV_AXEw(DWORD op) madr = calc_ea_dst(op); src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } - tmp = ((DWORD)CPU_DX << 16) + CPU_AX; + tmp = ((UINT32)CPU_DX << 16) + CPU_AX; if (src != 0) { - if (tmp < ((DWORD)src << 16)) { - CPU_AX = (WORD)(tmp / src); - CPU_DX = (WORD)(tmp % src); + if (tmp < ((UINT32)src << 16)) { + CPU_AX = (UINT16)(tmp / src); + CPU_DX = (UINT16)(tmp % src); return; } } @@ -1196,11 +398,11 @@ DIV_AXEw(DWORD op) } void -DIV_EAXEd(DWORD op) +DIV_EAXEd(UINT32 op) { - DWORD madr; - QWORD tmp; - DWORD src; + UINT32 madr; + UINT64 tmp; + UINT32 src; if (op >= 0xc0) { CPU_WORKCLOCK(17); @@ -1210,11 +412,11 @@ DIV_EAXEd(DWORD op) madr = calc_ea_dst(op); src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); } - tmp = ((QWORD)CPU_EDX << 32) + CPU_EAX; + tmp = ((UINT64)CPU_EDX << 32) + CPU_EAX; if (src != 0) { - if (tmp < ((QWORD)src << 32)) { - CPU_EAX = (DWORD)(tmp / src); - CPU_EDX = (DWORD)(tmp % src); + if (tmp < ((UINT64)src << 32)) { + CPU_EAX = (UINT32)(tmp / src); + CPU_EDX = (UINT32)(tmp % src); return; } } @@ -1225,65 +427,7 @@ DIV_EAXEd(DWORD op) /* * INC */ -void -INC_Eb(DWORD op) -{ - BYTE *out; - DWORD madr; - BYTE value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - BYTE_INC(*out); - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - value = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_INC(value); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, value); - } -} - -void -INC_Ew(DWORD op) -{ - WORD *out; - DWORD madr; - WORD value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - WORD_INC(*out); - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - value = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_INC(value); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, value); - } -} - -void -INC_Ed(DWORD op) -{ - DWORD *out; - DWORD madr; - DWORD value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - DWORD_INC(*out); - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - value = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_INC(value); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, value); - } -} +ARITH_INSTRUCTION_1(INC) void INC_AX(void) { WORD_INC(CPU_AX); CPU_WORKCLOCK(2); } void INC_CX(void) { WORD_INC(CPU_CX); CPU_WORKCLOCK(2); } @@ -1308,65 +452,7 @@ void INC_EDI(void) { DWORD_INC(CPU_EDI); /* * DEC */ -void -DEC_Eb(DWORD op) -{ - BYTE *out; - DWORD madr; - BYTE value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - BYTE_DEC(*out); - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - value = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_DEC(value); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, value); - } -} - -void -DEC_Ew(DWORD op) -{ - WORD *out; - DWORD madr; - WORD value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - WORD_DEC(*out); - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - value = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_DEC(value); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, value); - } -} - -void -DEC_Ed(DWORD op) -{ - DWORD *out; - DWORD madr; - DWORD value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - DWORD_DEC(*out); - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - value = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_DEC(value); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, value); - } -} +ARITH_INSTRUCTION_1(DEC) void DEC_AX(void) { WORD_DEC(CPU_AX); CPU_WORKCLOCK(2); } void DEC_CX(void) { WORD_DEC(CPU_CX); CPU_WORKCLOCK(2); } @@ -1390,53 +476,76 @@ void DEC_EDI(void) { DWORD_DEC(CPU_EDI); /* * NEG */ +static UINT32 +NEG1(UINT32 src, void *arg) +{ + UINT32 dst; + (void)arg; + BYTE_NEG(dst, src); + return dst; +} + +static UINT32 +NEG2(UINT32 src, void *arg) +{ + UINT32 dst; + (void)arg; + WORD_NEG(dst, src); + return dst; +} + +static UINT32 +NEG4(UINT32 src, void *arg) +{ + UINT32 dst; + (void)arg; + DWORD_NEG(dst, src); + return dst; +} + void -NEG_Eb(DWORD op) +NEG_Eb(UINT32 op) { - BYTE *out; - DWORD src, dst, madr; + UINT8 *out; + UINT32 src, dst, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); out = reg8_b20[op]; src = *out; BYTE_NEG(dst, src); - *out = (BYTE)dst; + *out = (UINT8)dst; } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); - src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_NEG(dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (BYTE)dst); + cpu_memory_access_va_RMW(CPU_INST_SEGREG_INDEX, madr, NEG1, 0); } } void -NEG_Ew(DWORD op) +NEG_Ew(UINT32 op) { - WORD *out; - DWORD src, dst, madr; + UINT16 *out; + UINT32 src, dst, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); out = reg16_b20[op]; src = *out; WORD_NEG(dst, src); - *out = (WORD)dst; + *out = (UINT16)dst; } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); - src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_NEG(dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)dst); + cpu_memory_access_va_RMW_w(CPU_INST_SEGREG_INDEX, madr, NEG2, 0); } } void -NEG_Ed(DWORD op) +NEG_Ed(UINT32 op) { - DWORD *out; - DWORD src, dst, madr; + UINT32 *out; + UINT32 src, dst, madr; if (op >= 0xc0) { CPU_WORKCLOCK(2); @@ -1447,9 +556,7 @@ NEG_Ed(DWORD op) } else { CPU_WORKCLOCK(7); madr = calc_ea_dst(op); - src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - DWORD_NEG(dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, dst); + cpu_memory_access_va_RMW_d(CPU_INST_SEGREG_INDEX, madr, NEG4, 0); } } @@ -1460,8 +567,8 @@ NEG_Ed(DWORD op) void CMP_EbGb(void) { - BYTE *out; - DWORD op, src, dst, res, madr; + UINT8 *out; + UINT32 op, src, dst, res, madr; PREPART_EA_REG8(op, src); if (op >= 0xc0) { @@ -1469,7 +576,7 @@ CMP_EbGb(void) out = reg8_b20[op]; dst = *out; } else { - CPU_WORKCLOCK(7); + CPU_WORKCLOCK(5); madr = calc_ea_dst(op); dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); } @@ -1479,8 +586,8 @@ CMP_EbGb(void) void CMP_EwGw(void) { - WORD *out; - DWORD op, src, dst, res, madr; + UINT16 *out; + UINT32 op, src, dst, res, madr; PREPART_EA_REG16(op, src); if (op >= 0xc0) { @@ -1488,7 +595,7 @@ CMP_EwGw(void) out = reg16_b20[op]; dst = *out; } else { - CPU_WORKCLOCK(7); + CPU_WORKCLOCK(5); madr = calc_ea_dst(op); dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } @@ -1498,8 +605,8 @@ CMP_EwGw(void) void CMP_EdGd(void) { - DWORD *out; - DWORD op, src, dst, res, madr; + UINT32 *out; + UINT32 op, src, dst, res, madr; PREPART_EA_REG32(op, src); if (op >= 0xc0) { @@ -1507,7 +614,7 @@ CMP_EdGd(void) out = reg32_b20[op]; dst = *out; } else { - CPU_WORKCLOCK(7); + CPU_WORKCLOCK(5); madr = calc_ea_dst(op); dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); } @@ -1517,10 +624,10 @@ CMP_EdGd(void) void CMP_GbEb(void) { - BYTE *out; - DWORD op, src, dst, res; + UINT8 *out; + UINT32 op, src, dst, res; - PREPART_REG8_EA(op, src, out, 2, 7); + PREPART_REG8_EA(op, src, out, 2, 5); dst = *out; BYTE_SUB(res, dst, src); } @@ -1528,10 +635,10 @@ CMP_GbEb(void) void CMP_GwEw(void) { - WORD *out; - DWORD op, src, dst, res; + UINT16 *out; + UINT32 op, src, dst, res; - PREPART_REG16_EA(op, src, out, 2, 7); + PREPART_REG16_EA(op, src, out, 2, 5); dst = *out; WORD_SUB(res, dst, src); } @@ -1539,10 +646,10 @@ CMP_GwEw(void) void CMP_GdEd(void) { - DWORD *out; - DWORD op, src, dst, res; + UINT32 *out; + UINT32 op, src, dst, res; - PREPART_REG32_EA(op, src, out, 2, 7); + PREPART_REG32_EA(op, src, out, 2, 5); dst = *out; DWORD_SUB(res, dst, src); } @@ -1550,82 +657,85 @@ CMP_GdEd(void) void CMP_ALIb(void) { - DWORD src, res; + UINT32 src, dst, res; - CPU_WORKCLOCK(3); + CPU_WORKCLOCK(2); GET_PCBYTE(src); - BYTE_SUB(res, CPU_AL, src); + dst = CPU_AL; + BYTE_SUB(res, dst, src); } void CMP_AXIw(void) { - DWORD src, res; + UINT32 src, dst, res; - CPU_WORKCLOCK(3); + CPU_WORKCLOCK(2); GET_PCWORD(src); - WORD_SUB(res, CPU_AX, src); + dst = CPU_AX; + WORD_SUB(res, dst, src); } void CMP_EAXId(void) { - DWORD src, res; + UINT32 src, dst, res; - CPU_WORKCLOCK(3); + CPU_WORKCLOCK(2); GET_PCDWORD(src); - DWORD_SUB(res, CPU_EAX, src); + dst = CPU_EAX; + DWORD_SUB(res, dst, src); } void -CMP_EbIb(BYTE *regp, DWORD src) +CMP_EbIb(UINT8 *regp, UINT32 src) { - DWORD dst, res; + UINT32 dst, res; dst = *regp; BYTE_SUB(res, dst, src); } void -CMP_EbIb_ext(DWORD madr, DWORD src) +CMP_EbIb_ext(UINT32 madr, UINT32 src) { - DWORD dst, res; + UINT32 dst, res; dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); BYTE_SUB(res, dst, src); } void -CMP_EwIx(WORD *regp, DWORD src) +CMP_EwIx(UINT16 *regp, UINT32 src) { - DWORD dst, res; + UINT32 dst, res; dst = *regp; WORD_SUB(res, dst, src); } void -CMP_EwIx_ext(DWORD madr, DWORD src) +CMP_EwIx_ext(UINT32 madr, UINT32 src) { - DWORD dst, res; + UINT32 dst, res; dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); WORD_SUB(res, dst, src); } void -CMP_EdIx(DWORD *regp, DWORD src) +CMP_EdIx(UINT32 *regp, UINT32 src) { - DWORD dst, res; + UINT32 dst, res; dst = *regp; DWORD_SUB(res, dst, src); } void -CMP_EdIx_ext(DWORD madr, DWORD src) +CMP_EdIx_ext(UINT32 madr, UINT32 src) { - DWORD dst, res; + UINT32 dst, res; dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); DWORD_SUB(res, dst, src);