From 79d5fb108f200bd1920f415bf1014ef0df53322b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 17 Nov 2016 21:36:09 +0100 Subject: [PATCH] Applied mainline PCem commit: Added code generation for RMW versions of SHL/SHR/SAR. --- src/codegen_ops_shift.h | 65 +++++++++++++++++++++++----------------- src/codegen_ops_x86-64.h | 2 ++ src/codegen_ops_x86.h | 1 + 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/codegen_ops_shift.h b/src/codegen_ops_shift.h index cedcf0c44..937a82ee8 100644 --- a/src/codegen_ops_shift.h +++ b/src/codegen_ops_shift.h @@ -1,6 +1,20 @@ -#define SHIFT(size, size2, count, res_store) \ +#define SHIFT(size, size2, res_store, immediate) \ + if ((fetchdat & 0xc0) == 0xc0) \ + { \ + reg = LOAD_REG_ ## size(fetchdat & 7); \ + if (immediate) count = (fetchdat >> 8) & 0x1f; \ + } \ + else \ + { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_ ## size(target_seg); \ + reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \ + if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \ + } \ STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, count); \ - reg = LOAD_REG_ ## size(fetchdat & 7); \ + \ res_store((uint32_t)&cpu_state.flags_op1, reg); \ \ switch (fetchdat & 0x38) \ @@ -22,93 +36,90 @@ } \ \ res_store((uint32_t)&cpu_state.flags_res, reg); \ - STORE_REG_ ## size ## _RELEASE(reg); + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_ ## size ## _RELEASE(reg); \ + else \ + { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \ + } static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + x86seg *target_seg; int count; int reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; if ((fetchdat & 0x38) < 0x20) return 0; - count = (fetchdat >> 8) & 0x1f; - - SHIFT(B, 8, count, STORE_HOST_REG_ADDR_BL); + SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); return op_pc + 2; } static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + x86seg *target_seg; int count; int reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; if ((fetchdat & 0x38) < 0x20) return 0; - count = (fetchdat >> 8) & 0x1f; - - SHIFT(W, 16, count, STORE_HOST_REG_ADDR_WL); + SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); return op_pc + 2; } static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + x86seg *target_seg; int count; int reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; if ((fetchdat & 0x38) < 0x20) return 0; - count = (fetchdat >> 8) & 0x1f; - - SHIFT(L, 32, count, STORE_HOST_REG_ADDR); + SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); return op_pc + 2; } static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + x86seg *target_seg; + int count = 1; int reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; if ((fetchdat & 0x38) < 0x20) return 0; - SHIFT(B, 8, 1, STORE_HOST_REG_ADDR_BL); + SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); return op_pc + 1; } static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + x86seg *target_seg; + int count = 1; int reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; if ((fetchdat & 0x38) < 0x20) return 0; - SHIFT(W, 16, 1, STORE_HOST_REG_ADDR_WL); + SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); return op_pc + 1; } static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + x86seg *target_seg; + int count = 1; int reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; if ((fetchdat & 0x38) < 0x20) return 0; - SHIFT(L, 32, 1, STORE_HOST_REG_ADDR); + SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); return op_pc + 1; } diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index d1747b9cf..319b6f13e 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -5147,6 +5147,8 @@ static void LOAD_EA() addbyte(0x24); } +#define MEM_CHECK_WRITE_B MEM_CHECK_WRITE + static void MEM_CHECK_WRITE(x86seg *seg) { uint8_t *jump1, *jump2; diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 2858ae59b..1ae11dd6e 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -3633,6 +3633,7 @@ static void LOAD_EA() addbyte(12); } +#define MEM_CHECK_WRITE_B MEM_CHECK_WRITE static void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg);