--- np2/i386c/ia32/instructions/bin_arith.c 2004/02/20 16:09:05 1.9 +++ np2/i386c/ia32/instructions/bin_arith.c 2012/01/08 19:09:40 1.16 @@ -1,851 +1,49 @@ -/* $Id: bin_arith.c,v 1.9 2004/02/20 16:09:05 monaka Exp $ */ - -/* - * Copyright (c) 2002-2003 NONAKA Kimihiro - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "compiler.h" -#include "cpu.h" -#include "ia32.mcr" - -#include "bin_arith.h" - - -/* - * ADD - */ -void -ADD_EbGb(void) -{ - UINT8 *out; - UINT32 op, src, dst, res, madr; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - dst = *out; - ADD_BYTE(res, dst, src); - *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); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); - } -} - -void -ADD_EwGw(void) -{ - UINT16 *out; - UINT32 op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - dst = *out; - ADD_WORD(res, dst, src); - *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); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); - } -} - -void -ADD_EdGd(void) -{ - UINT32 *out; - UINT32 op, src, dst, res, madr; - - PREPART_EA_REG32(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - dst = *out; - ADD_DWORD(res, dst, src); - *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); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); - } -} - -void -ADD_GbEb(void) -{ - UINT8 *out; - UINT32 op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - ADD_BYTE(res, dst, src); - *out = (UINT8)res; -} - -void -ADD_GwEw(void) -{ - UINT16 *out; - UINT32 op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - ADD_WORD(res, dst, src); - *out = (UINT16)res; -} - -void -ADD_GdEd(void) -{ - UINT32 *out; - UINT32 op, src, dst, res; - - PREPART_REG32_EA(op, src, out, 2, 7); - dst = *out; - ADD_DWORD(res, dst, src); - *out = res; -} - -void -ADD_ALIb(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCBYTE(src); - dst = CPU_AL; - ADD_BYTE(res, dst, src); - CPU_AL = (UINT8)res; -} - -void -ADD_AXIw(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCWORD(src); - dst = CPU_AX; - ADD_WORD(res, dst, src); - CPU_AX = (UINT16)res; -} - -void -ADD_EAXId(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCDWORD(src); - dst = CPU_EAX; - ADD_DWORD(res, dst, src); - CPU_EAX = res; -} - -void -ADD_EbIb(UINT8 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - ADD_BYTE(res, dst, src); - *regp = (UINT8)res; -} - -void -ADD_EbIb_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADD_BYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); -} - -void -ADD_EwIx(UINT16 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - ADD_WORD(res, dst, src); - *regp = (UINT16)res; -} - -void -ADD_EwIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADD_WORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); -} - -void -ADD_EdIx(UINT32 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - ADD_DWORD(res, dst, src); - *regp = res; -} - -void -ADD_EdIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADD_DWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); -} - - -/* - * ADC - */ -void -ADC_EbGb(void) -{ - UINT8 *out; - UINT32 op, src, dst, res, madr; - - PREPART_EA_REG8(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - dst = *out; - ADC_BYTE(res, dst, src); - *out = (UINT8)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADC_BYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); - } -} - -void -ADC_EwGw(void) -{ - UINT16 *out; - UINT32 op, src, dst, res, madr; - - PREPART_EA_REG16(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - dst = *out; - ADC_WORD(res, dst, src); - *out = (UINT16)res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADC_WORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); - } -} - -void -ADC_EdGd(void) -{ - UINT32 *out; - UINT32 op, src, dst, res, madr; - - PREPART_EA_REG32(op, src); - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - dst = *out; - ADC_DWORD(res, dst, src); - *out = res; - } else { - CPU_WORKCLOCK(7); - madr = calc_ea_dst(op); - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADC_DWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); - } -} - -void -ADC_GbEb(void) -{ - UINT8 *out; - UINT32 op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - ADC_BYTE(res, dst, src); - *out = (UINT8)res; -} - -void -ADC_GwEw(void) -{ - UINT16 *out; - UINT32 op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - ADC_WORD(res, dst, src); - *out = (UINT16)res; -} - -void -ADC_GdEd(void) -{ - UINT32 *out; - UINT32 op, src, dst, res; - - PREPART_REG32_EA(op, src, out, 2, 7); - dst = *out; - ADC_DWORD(res, dst, src); - *out = res; -} - -void -ADC_ALIb(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCBYTE(src); - dst = CPU_AL; - ADC_BYTE(res, dst, src); - CPU_AL = (UINT8)res; -} - -void -ADC_AXIw(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCWORD(src); - dst = CPU_AX; - ADC_WORD(res, dst, src); - CPU_AX = (UINT16)res; -} - -void -ADC_EAXId(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCDWORD(src); - dst = CPU_EAX; - ADC_DWORD(res, dst, src); - CPU_EAX = res; -} - -void -ADC_EbIb(UINT8 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - ADC_BYTE(res, dst, src); - *regp = (UINT8)res; -} - -void -ADC_EbIb_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - ADC_BYTE(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); -} - -void -ADC_EwIx(UINT16 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - ADC_WORD(res, dst, src); - *regp = (UINT16)res; -} - -void -ADC_EwIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - ADC_WORD(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); -} - -void -ADC_EdIx(UINT32 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - ADC_DWORD(res, dst, src); - *regp = res; -} - -void -ADC_EdIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - ADC_DWORD(res, dst, src); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); -} - - -/* - * SUB - */ -void -SUB_EbGb(void) -{ - UINT8 *out; - UINT32 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 = (UINT8)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, (UINT8)res); - } -} - -void -SUB_EwGw(void) -{ - UINT16 *out; - UINT32 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 = (UINT16)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, (UINT16)res); - } -} - -void -SUB_EdGd(void) -{ - UINT32 *out; - UINT32 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) -{ - UINT8 *out; - UINT32 op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - BYTE_SUB(res, dst, src); - *out = (UINT8)res; -} - -void -SUB_GwEw(void) -{ - UINT16 *out; - UINT32 op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - WORD_SUB(res, dst, src); - *out = (UINT16)res; -} - -void -SUB_GdEd(void) -{ - UINT32 *out; - UINT32 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) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCBYTE(src); - dst = CPU_AL; - BYTE_SUB(res, dst, src); - CPU_AL = (UINT8)res; -} - -void -SUB_AXIw(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCWORD(src); - dst = CPU_AX; - WORD_SUB(res, dst, src); - CPU_AX = (UINT16)res; -} - -void -SUB_EAXId(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCDWORD(src); - dst = CPU_EAX; - DWORD_SUB(res, dst, src); - CPU_EAX = res; -} - -void -SUB_EbIb(UINT8 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - BYTE_SUB(res, dst, src); - *regp = (UINT8)res; -} - -void -SUB_EbIb_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SUB(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); -} - -void -SUB_EwIx(UINT16 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - WORD_SUB(res, dst, src); - *regp = (UINT16)res; -} - -void -SUB_EwIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SUB(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); -} - -void -SUB_EdIx(UINT32 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - DWORD_SUB(res, dst, src); - *regp = res; -} - -void -SUB_EdIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 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) -{ - UINT8 *out; - UINT32 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 = (UINT8)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, (UINT8)res); - } -} - -void -SBB_EwGw(void) -{ - UINT16 *out; - UINT32 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 = (UINT16)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, (UINT16)res); - } -} - -void -SBB_EdGd(void) -{ - UINT32 *out; - UINT32 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) -{ - UINT8 *out; - UINT32 op, src, dst, res; - - PREPART_REG8_EA(op, src, out, 2, 7); - dst = *out; - BYTE_SBB(res, dst, src); - *out = (UINT8)res; -} - -void -SBB_GwEw(void) -{ - UINT16 *out; - UINT32 op, src, dst, res; - - PREPART_REG16_EA(op, src, out, 2, 7); - dst = *out; - WORD_SBB(res, dst, src); - *out = (UINT16)res; -} - -void -SBB_GdEd(void) -{ - UINT32 *out; - UINT32 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) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCBYTE(src); - dst = CPU_AL; - BYTE_SBB(res, dst, src); - CPU_AL = (UINT8)res; -} - -void -SBB_AXIw(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCWORD(src); - dst = CPU_AX; - WORD_SBB(res, dst, src); - CPU_AX = (UINT16)res; -} - -void -SBB_EAXId(void) -{ - UINT32 src, dst, res; - - CPU_WORKCLOCK(2); - GET_PCDWORD(src); - dst = CPU_EAX; - DWORD_SBB(res, dst, src); - CPU_EAX = res; -} - -void -SBB_EbIb(UINT8 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - BYTE_SBB(res, dst, src); - *regp = (UINT8)res; -} - -void -SBB_EbIb_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); - BYTE_SBB(res, dst, src); - cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); -} - -void -SBB_EwIx(UINT16 *regp, UINT32 src) -{ - UINT32 dst, res; - - dst = *regp; - WORD_SBB(res, dst, src); - *regp = (UINT16)res; -} - -void -SBB_EwIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 dst, res; - - dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - WORD_SBB(res, dst, src); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); -} +/* + * Copyright (c) 2002-2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ -void -SBB_EdIx(UINT32 *regp, UINT32 src) -{ - UINT32 dst, res; +#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" +#include "arith.mcr" - dst = *regp; - DWORD_SBB(res, dst, src); - *regp = res; -} +#include "bin_arith.h" -void -SBB_EdIx_ext(UINT32 madr, UINT32 src) -{ - UINT32 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 + */ +ARITH_INSTRUCTION_3(ADD) +ARITH_INSTRUCTION_3(ADC) +ARITH_INSTRUCTION_3(SUB) +ARITH_INSTRUCTION_3(SBB) /* * IMUL */ -void +void CPUCALL IMUL_ALEb(UINT32 op) { UINT32 madr; @@ -865,7 +63,7 @@ IMUL_ALEb(UINT32 op) CPU_AX = (UINT16)res; } -void +void CPUCALL IMUL_AXEw(UINT32 op) { UINT32 madr; @@ -886,7 +84,7 @@ IMUL_AXEw(UINT32 op) CPU_DX = (UINT16)(res >> 16); } -void +void CPUCALL IMUL_EAXEd(UINT32 op) { UINT32 madr; @@ -995,7 +193,7 @@ IMUL_GdEdId(void) /* * MUL */ -void +void CPUCALL MUL_ALEb(UINT32 op) { UINT32 res, madr; @@ -1014,7 +212,7 @@ MUL_ALEb(UINT32 op) CPU_AX = (UINT16)res; } -void +void CPUCALL MUL_AXEw(UINT32 op) { UINT32 res, madr; @@ -1034,7 +232,7 @@ MUL_AXEw(UINT32 op) CPU_DX = (UINT16)(res >> 16); } -void +void CPUCALL MUL_EAXEd(UINT32 op) { UINT32 res, madr; @@ -1058,7 +256,7 @@ MUL_EAXEd(UINT32 op) /* * IDIV */ -void +void CPUCALL IDIV_ALEb(UINT32 op) { UINT32 madr; @@ -1079,13 +277,16 @@ IDIV_ALEb(UINT32 op) if (((r + 0x80) & 0xff00) == 0) { CPU_AL = (SINT8)r; CPU_AH = tmp % src; +#if (CPU_FAMILY == 4) + CPU_FLAGL ^= A_FLAG; +#endif return; } } EXCEPTION(DE_EXCEPTION, 0); } -void +void CPUCALL IDIV_AXEw(UINT32 op) { SINT32 tmp, r; @@ -1106,13 +307,16 @@ IDIV_AXEw(UINT32 op) if (((r + 0x8000) & 0xffff0000) == 0) { CPU_AX = (SINT16)r; CPU_DX = tmp % src; +#if (CPU_FAMILY == 4) + CPU_FLAGL ^= A_FLAG; +#endif return; } } EXCEPTION(DE_EXCEPTION, 0); } -void +void CPUCALL IDIV_EAXEd(UINT32 op) { SINT64 tmp, r; @@ -1133,6 +337,9 @@ IDIV_EAXEd(UINT32 op) if (((r + SQWORD_CONST(0x80000000)) & QWORD_CONST(0xffffffff00000000)) == 0) { CPU_EAX = (SINT32)r; CPU_EDX = (SINT32)(tmp % src); +#if (CPU_FAMILY == 4) + CPU_FLAGL ^= A_FLAG; +#endif return; } } @@ -1143,7 +350,7 @@ IDIV_EAXEd(UINT32 op) /* * DIV */ -void +void CPUCALL DIV_ALEb(UINT32 op) { UINT32 madr; @@ -1163,13 +370,16 @@ DIV_ALEb(UINT32 op) if (tmp < ((UINT16)src << 8)) { CPU_AL = tmp / src; CPU_AH = tmp % src; +#if (CPU_FAMILY == 4) + CPU_FLAGL ^= A_FLAG; +#endif return; } } EXCEPTION(DE_EXCEPTION, 0); } -void +void CPUCALL DIV_AXEw(UINT32 op) { UINT32 madr; @@ -1189,13 +399,16 @@ DIV_AXEw(UINT32 op) if (tmp < ((UINT32)src << 16)) { CPU_AX = (UINT16)(tmp / src); CPU_DX = (UINT16)(tmp % src); +#if (CPU_FAMILY == 4) + CPU_FLAGL ^= A_FLAG; +#endif return; } } EXCEPTION(DE_EXCEPTION, 0); } -void +void CPUCALL DIV_EAXEd(UINT32 op) { UINT32 madr; @@ -1215,6 +428,9 @@ DIV_EAXEd(UINT32 op) if (tmp < ((UINT64)src << 32)) { CPU_EAX = (UINT32)(tmp / src); CPU_EDX = (UINT32)(tmp % src); +#if (CPU_FAMILY == 4) + CPU_FLAGL ^= A_FLAG; +#endif return; } } @@ -1225,71 +441,7 @@ DIV_EAXEd(UINT32 op) /* * INC */ -void -INC_Eb(UINT32 op) -{ - UINT8 *out; - UINT32 madr; - UINT8 value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - value = *out; - BYTE_INC(value); - *out = value; - } else { - CPU_WORKCLOCK(6); - 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(UINT32 op) -{ - UINT16 *out; - UINT32 madr; - UINT16 value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - value = *out; - WORD_INC(value); - *out = value; - } else { - CPU_WORKCLOCK(6); - 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(UINT32 op) -{ - UINT32 *out; - UINT32 madr; - UINT32 value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(6); - out = reg32_b20[op]; - value = *out; - DWORD_INC(value); - *out = value; - } 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); } @@ -1314,71 +466,7 @@ void INC_EDI(void) { DWORD_INC(CPU_EDI); /* * DEC */ -void -DEC_Eb(UINT32 op) -{ - UINT8 *out; - UINT32 madr; - UINT8 value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg8_b20[op]; - value = *out; - BYTE_DEC(value); - *out = value; - } else { - CPU_WORKCLOCK(6); - 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(UINT32 op) -{ - UINT16 *out; - UINT32 madr; - UINT16 value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg16_b20[op]; - value = *out; - WORD_DEC(value); - *out = value; - } else { - CPU_WORKCLOCK(6); - 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(UINT32 op) -{ - UINT32 *out; - UINT32 madr; - UINT32 value; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - out = reg32_b20[op]; - value = *out; - DWORD_DEC(value); - *out = value; - } else { - CPU_WORKCLOCK(6); - 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); } @@ -1402,7 +490,31 @@ void DEC_EDI(void) { DWORD_DEC(CPU_EDI); /* * NEG */ -void +static UINT32 CPUCALL +NEG1(UINT32 src, void *arg) +{ + UINT32 dst; + BYTE_NEG(dst, src); + return dst; +} + +static UINT32 CPUCALL +NEG2(UINT32 src, void *arg) +{ + UINT32 dst; + WORD_NEG(dst, src); + return dst; +} + +static UINT32 CPUCALL +NEG4(UINT32 src, void *arg) +{ + UINT32 dst; + DWORD_NEG(dst, src); + return dst; +} + +void CPUCALL NEG_Eb(UINT32 op) { UINT8 *out; @@ -1415,15 +527,13 @@ NEG_Eb(UINT32 op) BYTE_NEG(dst, src); *out = (UINT8)dst; } else { - CPU_WORKCLOCK(6); + 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, (UINT8)dst); + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, NEG1, 0); } } -void +void CPUCALL NEG_Ew(UINT32 op) { UINT16 *out; @@ -1436,15 +546,13 @@ NEG_Ew(UINT32 op) WORD_NEG(dst, src); *out = (UINT16)dst; } else { - CPU_WORKCLOCK(6); + 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, (UINT16)dst); + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, NEG2, 0); } } -void +void CPUCALL NEG_Ed(UINT32 op) { UINT32 *out; @@ -1457,11 +565,9 @@ NEG_Ed(UINT32 op) DWORD_NEG(dst, src); *out = dst; } else { - CPU_WORKCLOCK(6); + 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_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, NEG4, 0); } } @@ -1592,7 +698,7 @@ CMP_EAXId(void) DWORD_SUB(res, dst, src); } -void +void CPUCALL CMP_EbIb(UINT8 *regp, UINT32 src) { UINT32 dst, res; @@ -1601,7 +707,7 @@ CMP_EbIb(UINT8 *regp, UINT32 src) BYTE_SUB(res, dst, src); } -void +void CPUCALL CMP_EbIb_ext(UINT32 madr, UINT32 src) { UINT32 dst, res; @@ -1610,7 +716,7 @@ CMP_EbIb_ext(UINT32 madr, UINT32 src) BYTE_SUB(res, dst, src); } -void +void CPUCALL CMP_EwIx(UINT16 *regp, UINT32 src) { UINT32 dst, res; @@ -1619,7 +725,7 @@ CMP_EwIx(UINT16 *regp, UINT32 src) WORD_SUB(res, dst, src); } -void +void CPUCALL CMP_EwIx_ext(UINT32 madr, UINT32 src) { UINT32 dst, res; @@ -1628,7 +734,7 @@ CMP_EwIx_ext(UINT32 madr, UINT32 src) WORD_SUB(res, dst, src); } -void +void CPUCALL CMP_EdIx(UINT32 *regp, UINT32 src) { UINT32 dst, res; @@ -1637,7 +743,7 @@ CMP_EdIx(UINT32 *regp, UINT32 src) DWORD_SUB(res, dst, src); } -void +void CPUCALL CMP_EdIx_ext(UINT32 madr, UINT32 src) { UINT32 dst, res;