diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index ebef0fc..1c29270 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -195,6 +195,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm64_call(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1413,6 +1420,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 427da2e..6a65d3b 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -268,6 +268,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1493,6 +1500,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 59f78b3..9e14a0b 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -149,6 +149,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_x86_CALL(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1205,6 +1212,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 4f1ceb8..5bca500 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -159,6 +159,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_x86_CALL(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1198,6 +1205,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_ops.c b/src/codegen_ops.c index ff7df3d..d4bfd76 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -20,7 +20,7 @@ RecompOpFn recomp_opcodes[512] = /*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, /*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8,NULL, NULL, NULL, NULL, NULL, /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, @@ -33,7 +33,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_16, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -42,7 +42,7 @@ RecompOpFn recomp_opcodes[512] = /*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, /*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8,NULL, NULL, NULL, NULL, NULL, /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, @@ -55,7 +55,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_32 }; diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 7331afc..1a9c8d1 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -1330,3 +1330,130 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_flags_changed = 1; return op_pc + 2; } + +static void rebuild_c(ir_data_t *ir) +{ + int needs_rebuild = 1; + + if (codegen_flags_changed) + { + switch (cpu_state.flags_op) + { + case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: + case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) + { + uop_CALL_FUNC(ir, flags_rebuild_c); + } +} + +uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); + if (fetchdat & 0x38) + { + uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } + else + { + uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + + if (fetchdat & 0x38) + { + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } + else + { + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) + { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } + else + { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + } + + return op_pc+1; +} diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h index 2faa55d..75a70b2 100644 --- a/src/codegen_ops_arith.h +++ b/src/codegen_ops_arith.h @@ -33,3 +33,12 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + + +uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 01c404f..999e17c 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -238,28 +238,97 @@ uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return 0; } +static void rebuild_c(ir_data_t *ir) +{ + int needs_rebuild = 1; + + if (codegen_flags_changed) + { + switch (cpu_state.flags_op) + { + case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: + case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) + { + uop_CALL_FUNC(ir, flags_rebuild_c); + } +} + uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + x86seg *target_seg = NULL; int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) return 0; - + if ((fetchdat & 0xc0) == 0xc0) src_reg = IREG_16(fetchdat & 7); else { - x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); src_reg = IREG_temp0_W; } switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + else + { + uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + return op_pc+1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + else + { + uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + return op_pc+1; + case 0x10: /*CALL*/ if ((fetchdat & 0xc0) == 0xc0) uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -286,26 +355,74 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + x86seg *target_seg = NULL; int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) return 0; if ((fetchdat & 0xc0) == 0xc0) src_reg = IREG_32(fetchdat & 7); else { - x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); src_reg = IREG_temp0; } switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + else + { + uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + return op_pc+1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + else + { + uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + return op_pc+1; + case 0x10: /*CALL*/ if ((fetchdat & 0xc0) == 0xc0) uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);