From ea5e96569de985b41ede4da3b3f0ac5a8f3de383 Mon Sep 17 00:00:00 2001 From: TomW Date: Mon, 2 Feb 2015 19:54:01 +0000 Subject: [PATCH] Lazy flags code now handles carry flag. --- src/386.c | 1 - src/386_dynarec.c | 2 - src/codegen_ops_arith.h | 77 ++++++++---------------- src/codegen_ops_logic.h | 18 ------ src/codegen_ops_x86.h | 25 +------- src/x86_flags.h | 130 ++++++++++++++++++++++++++++------------ src/x86_ops_arith.h | 48 ++++++++------- src/x86_ops_shift.h | 35 ++--------- 8 files changed, 147 insertions(+), 189 deletions(-) diff --git a/src/386.c b/src/386.c index 3c92623..6007e13 100644 --- a/src/386.c +++ b/src/386.c @@ -1130,7 +1130,6 @@ opcodestart: if (!abrt) { - tempc = CF_SET(); trap = flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 053babb..c26a7ab 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1212,7 +1212,6 @@ void exec386(int cycs) // fatal("Dead with cache off\n"); if (!abrt) { - tempc = CF_SET(); trap = flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; @@ -1348,7 +1347,6 @@ inrecomp=0; // fatal("Dead\n"); if (!abrt) { - tempc = CF_SET(); trap = flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h index e99ccae..152e6ad 100644 --- a/src/codegen_ops_arith.h +++ b/src/codegen_ops_arith.h @@ -1,12 +1,16 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_W(opcode & 7); + int host_reg; + + CALL_FUNC(flags_rebuild_c); + + host_reg = LOAD_REG_W(opcode & 7); STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); ADD_HOST_REG_IMM(host_reg, 1); STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1); AND_HOST_REG_IMM(host_reg, 0xffff); - STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); + STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_INC16); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -14,12 +18,16 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_L(opcode & 7); + int host_reg; + + CALL_FUNC(flags_rebuild_c); + + host_reg = LOAD_REG_L(opcode & 7); STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); ADD_HOST_REG_IMM(host_reg, 1); STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32); + STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_INC32); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); @@ -27,13 +35,17 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_W(opcode & 7); + int host_reg; + + CALL_FUNC(flags_rebuild_c); + + host_reg = LOAD_REG_W(opcode & 7); STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, 1); STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1); AND_HOST_REG_IMM(host_reg, 0xffff); - STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); + STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_DEC16); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -41,12 +53,16 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_L(opcode & 7); + int host_reg; + + CALL_FUNC(flags_rebuild_c); + + host_reg = LOAD_REG_L(opcode & 7); STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, 1); STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); + STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_DEC32); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); @@ -67,7 +83,6 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ op ## _HOST_REG_B(dst_reg, src_reg); \ STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ - FLAG_C_COPY(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -88,7 +103,6 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ op ## _HOST_REG_W(dst_reg, src_reg); \ STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ - FLAG_C_COPY(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -109,7 +123,6 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ op ## _HOST_REG_L(dst_reg, src_reg); \ STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ - FLAG_C_COPY(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -130,7 +143,6 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ op ## _HOST_REG_B(dst_reg, src_reg); \ STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ - FLAG_C_COPY(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -151,7 +163,6 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ op ## _HOST_REG_W(dst_reg, src_reg); \ STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ - FLAG_C_COPY(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -172,7 +183,6 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ op ## _HOST_REG_L(dst_reg, src_reg); \ STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ - FLAG_C_COPY(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -193,7 +203,6 @@ static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); @@ -207,7 +216,6 @@ static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -222,7 +230,6 @@ static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 ADD_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); @@ -237,7 +244,6 @@ static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); RELEASE_REG(host_reg); @@ -251,7 +257,6 @@ static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); RELEASE_REG(host_reg); @@ -266,7 +271,6 @@ static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 SUB_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); RELEASE_REG(host_reg); @@ -281,7 +285,6 @@ static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); @@ -295,7 +298,6 @@ static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -310,7 +312,6 @@ static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 SUB_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); - FLAG_C_COPY(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); @@ -335,36 +336,30 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ ADD_HOST_REG_IMM_B(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8); - FLAG_C_COPY(); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); break; case 0x28: /*SUB*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM_B(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); - FLAG_C_COPY(); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); break; case 0x38: /*CMP*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM_B(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); - FLAG_C_COPY(); break; } @@ -395,36 +390,30 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 ADD_HOST_REG_IMM_W(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); - FLAG_C_COPY(); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); break; case 0x28: /*SUB*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); - FLAG_C_COPY(); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); break; case 0x38: /*CMP*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); - FLAG_C_COPY(); break; } @@ -455,36 +444,30 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 ADD_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32); - FLAG_C_COPY(); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); break; case 0x28: /*SUB*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); - FLAG_C_COPY(); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); break; case 0x38: /*CMP*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); - FLAG_C_COPY(); break; } @@ -517,36 +500,30 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 ADD_HOST_REG_IMM_W(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); - FLAG_C_COPY(); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); break; case 0x28: /*SUB*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); - FLAG_C_COPY(); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); break; case 0x38: /*CMP*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); - FLAG_C_COPY(); break; } @@ -578,36 +555,30 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 ADD_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32); - FLAG_C_COPY(); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); break; case 0x28: /*SUB*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); - FLAG_C_COPY(); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); break; case 0x38: /*CMP*/ STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); - FLAG_C_COPY(); break; } diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h index eefc450..6aaa15d 100644 --- a/src/codegen_ops_logic.h +++ b/src/codegen_ops_logic.h @@ -10,7 +10,6 @@ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); \ src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ op ## _HOST_REG_B(dst_reg, src_reg); \ - FLAG_C_CLEAR(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -29,7 +28,6 @@ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); \ src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ op ## _HOST_REG_W(dst_reg, src_reg); \ - FLAG_C_CLEAR(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -48,7 +46,6 @@ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); \ src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ op ## _HOST_REG_L(dst_reg, src_reg); \ - FLAG_C_CLEAR(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -67,7 +64,6 @@ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); \ src_reg = LOAD_REG_B(fetchdat & 7); \ op ## _HOST_REG_B(dst_reg, src_reg); \ - FLAG_C_CLEAR(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -86,7 +82,6 @@ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); \ src_reg = LOAD_REG_W(fetchdat & 7); \ op ## _HOST_REG_W(dst_reg, src_reg); \ - FLAG_C_CLEAR(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -105,7 +100,6 @@ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); \ src_reg = LOAD_REG_L(fetchdat & 7); \ op ## _HOST_REG_L(dst_reg, src_reg); \ - FLAG_C_CLEAR(); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ @@ -125,7 +119,6 @@ static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, AND_HOST_REG_IMM(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); @@ -137,7 +130,6 @@ static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, AND_HOST_REG_IMM(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -150,7 +142,6 @@ static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 fetchdat = fastreadl(cs + op_pc); AND_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); @@ -163,7 +154,6 @@ static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); @@ -175,7 +165,6 @@ static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -188,7 +177,6 @@ static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, fetchdat = fastreadl(cs + op_pc); OR_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); @@ -201,7 +189,6 @@ static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 AND_HOST_REG_IMM(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); RELEASE_REG(host_reg); @@ -213,7 +200,6 @@ static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 AND_HOST_REG_IMM(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); RELEASE_REG(host_reg); @@ -226,7 +212,6 @@ static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_3 fetchdat = fastreadl(cs + op_pc); AND_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); RELEASE_REG(host_reg); @@ -239,7 +224,6 @@ static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); @@ -251,7 +235,6 @@ static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); @@ -264,7 +247,6 @@ static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 fetchdat = fastreadl(cs + op_pc); XOR_HOST_REG_IMM(host_reg, fetchdat); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); - FLAG_C_CLEAR(); STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index ced357a..37cf36e 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -279,27 +279,8 @@ static void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) addlong(imm); } -static void FLAG_C_CLEAR() +static void CALL_FUNC(void *dest) { - addbyte(0x83); /*ANDL [flags],~1*/ - addbyte(0x25); - addlong((uint32_t)&flags); - addbyte(0xfe); -} -static void FLAG_C_COPY() -{ - addbyte(0x8a); /*MOVB DL, [flags]*/ - addbyte(0x05 | (REG_DL << 3)); - addlong((uint32_t)&flags); - addbyte(0x0f); /*SETB DH*/ - addbyte(0x92); - addbyte(0xc0 | REG_DH); - addbyte(0x80); /*AND DL, ~1*/ - addbyte(0xe0 | REG_DL); - addbyte(0xfe); - addbyte(0x08); /*OR DL, DH*/ - addbyte(0xc0 | REG_DL | (REG_DH << 3)); - addbyte(0x88); /*MOVB [flags],DL*/ - addbyte(0x05 | (REG_DL << 3)); - addlong((uint32_t)&flags); + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *)dest - (uint8_t *)(&codeblock[block_current].data[block_pos + 4]))); } diff --git a/src/x86_flags.h b/src/x86_flags.h index ff23dfa..d397433 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -25,6 +25,14 @@ enum FLAGS_SAR8, FLAGS_SAR16, FLAGS_SAR32, + + FLAGS_INC8, + FLAGS_INC16, + FLAGS_INC32, + + FLAGS_DEC8, + FLAGS_DEC16, + FLAGS_DEC32, }; int flags_op; @@ -53,6 +61,12 @@ static inline int ZF_SET() case FLAGS_SAR8: case FLAGS_SAR16: case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: return !flags_res; case FLAGS_UNKNOWN: @@ -70,6 +84,8 @@ static inline int NF_SET() case FLAGS_SHL8: case FLAGS_SHR8: case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: return flags_res & 0x80; case FLAGS_ZN16: @@ -78,6 +94,8 @@ static inline int NF_SET() case FLAGS_SHL16: case FLAGS_SHR16: case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: return flags_res & 0x8000; case FLAGS_ZN32: @@ -86,6 +104,8 @@ static inline int NF_SET() case FLAGS_SHL32: case FLAGS_SHR32: case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: return flags_res & 0x80000000; case FLAGS_UNKNOWN: @@ -115,6 +135,12 @@ static inline int PF_SET() case FLAGS_SAR8: case FLAGS_SAR16: case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: return znptable8[flags_res & 0xff] & P_FLAG; case FLAGS_UNKNOWN: @@ -135,17 +161,23 @@ static inline int VF_SET() return 0; case FLAGS_ADD8: + case FLAGS_INC8: return !((flags_op1 ^ flags_op2) & 0x80) && ((flags_op1 ^ flags_res) & 0x80); case FLAGS_ADD16: + case FLAGS_INC16: return !((flags_op1 ^ flags_op2) & 0x8000) && ((flags_op1 ^ flags_res) & 0x8000); case FLAGS_ADD32: + case FLAGS_INC32: return !((flags_op1 ^ flags_op2) & 0x80000000) && ((flags_op1 ^ flags_res) & 0x80000000); case FLAGS_SUB8: + case FLAGS_DEC8: return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80); case FLAGS_SUB16: + case FLAGS_DEC16: return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x8000); case FLAGS_SUB32: + case FLAGS_DEC32: return ((flags_op1 ^ flags_op2) & (flags_op1 ^ flags_res) & 0x80000000); case FLAGS_SHL8: @@ -188,11 +220,17 @@ static inline int AF_SET() case FLAGS_ADD8: case FLAGS_ADD16: case FLAGS_ADD32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: return ((flags_op1 & 0xF) + (flags_op2 & 0xF)) & 0x10; case FLAGS_SUB8: case FLAGS_SUB16: case FLAGS_SUB32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: return ((flags_op1 & 0xF) - (flags_op2 & 0xF)) & 0x10; case FLAGS_UNKNOWN: @@ -200,32 +238,62 @@ static inline int AF_SET() } } -#if 0 static inline int CF_SET() { switch (flags_op) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - return flags & C_FLAG; /*Temporary*/ - case FLAGS_ADD8: return (flags_op1 + flags_op2) & 0x100; case FLAGS_ADD16: -// return (flags_op1 + flags_op2) & 0x10000; - + return (flags_op1 + flags_op2) & 0x10000; + case FLAGS_ADD32: + return (flags_res < flags_op1); + + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + return (flags_op1 < flags_op2); + + case FLAGS_SHL8: + return (flags_op1 << (flags_op2 - 1)) & 0x80; + case FLAGS_SHL16: + return (flags_op1 << (flags_op2 - 1)) & 0x8000; + case FLAGS_SHL32: + return (flags_op1 << (flags_op2 - 1)) & 0x80000000; + + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + return (flags_op1 >> (flags_op2 - 1)) & 1; + + case FLAGS_SAR8: + return ((int8_t)flags_op1 >> (flags_op2 - 1)) & 1; + case FLAGS_SAR16: + return ((int16_t)flags_op1 >> (flags_op2 - 1)) & 1; + case FLAGS_SAR32: + return ((int32_t)flags_op1 >> (flags_op2 - 1)) & 1; + + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + return 0; + + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: case FLAGS_UNKNOWN: return flags & C_FLAG; } } -#endif //#define ZF_SET() (flags & Z_FLAG) //#define NF_SET() (flags & N_FLAG) //#define PF_SET() (flags & P_FLAG) //#define VF_SET() (flags & V_FLAG) -#define CF_SET() (flags & C_FLAG) +//#define CF_SET() (flags & C_FLAG) //#define AF_SET() (flags & A_FLAG) static inline void flags_rebuild() @@ -264,27 +332,23 @@ static inline void setznp8(uint8_t val) { flags_op = FLAGS_ZN8; flags_res = val; - flags &= ~C_FLAG; } static inline void setznp16(uint16_t val) { flags_op = FLAGS_ZN16; flags_res = val; - flags &= ~C_FLAG; } static inline void setznp32(uint32_t val) { flags_op = FLAGS_ZN32; flags_res = val; - flags &= ~C_FLAG; } #define set_flags_shift(op, orig, shift, res) \ flags_op = op; \ flags_res = res; \ flags_op1 = orig; \ - flags_op2 = shift; \ - flags &= ~C_FLAG; + flags_op2 = shift; static inline void setadd8(uint8_t a, uint8_t b) { @@ -292,9 +356,6 @@ static inline void setadd8(uint8_t a, uint8_t b) flags_op2 = b; flags_res = (a + b) & 0xff; flags_op = FLAGS_ADD8; - - if ((a + b) & 0x100) flags |= C_FLAG; - else flags &= ~C_FLAG; } static inline void setadd16(uint16_t a, uint16_t b) { @@ -302,9 +363,6 @@ static inline void setadd16(uint16_t a, uint16_t b) flags_op2 = b; flags_res = (a + b) & 0xffff; flags_op = FLAGS_ADD16; - - if ((a + b) & 0x10000) flags |= C_FLAG; - else flags &= ~C_FLAG; } static inline void setadd32(uint32_t a, uint32_t b) { @@ -312,30 +370,30 @@ static inline void setadd32(uint32_t a, uint32_t b) flags_op2 = b; flags_res = a + b; flags_op = FLAGS_ADD32; - - if (flags_res < a) flags |= C_FLAG; - else flags &= ~C_FLAG; } static inline void setadd8nc(uint8_t a, uint8_t b) { + flags_rebuild_c(); flags_op1 = a; flags_op2 = b; flags_res = (a + b) & 0xff; - flags_op = FLAGS_ADD8; + flags_op = FLAGS_INC8; } static inline void setadd16nc(uint16_t a, uint16_t b) { + flags_rebuild_c(); flags_op1 = a; flags_op2 = b; flags_res = (a + b) & 0xffff; - flags_op = FLAGS_ADD16; + flags_op = FLAGS_INC16; } static inline void setadd32nc(uint32_t a, uint32_t b) { + flags_rebuild_c(); flags_op1 = a; flags_op2 = b; flags_res = a + b; - flags_op = FLAGS_ADD32; + flags_op = FLAGS_INC32; } static inline void setsub8(uint8_t a, uint8_t b) @@ -344,9 +402,6 @@ static inline void setsub8(uint8_t a, uint8_t b) flags_op2 = b; flags_res = (a - b) & 0xff; flags_op = FLAGS_SUB8; - - if (a < b) flags |= C_FLAG; - else flags &= ~C_FLAG; } static inline void setsub16(uint16_t a, uint16_t b) { @@ -354,9 +409,6 @@ static inline void setsub16(uint16_t a, uint16_t b) flags_op2 = b; flags_res = (a - b) & 0xffff; flags_op = FLAGS_SUB16; - - if (a < b) flags |= C_FLAG; - else flags &= ~C_FLAG; } static inline void setsub32(uint32_t a, uint32_t b) { @@ -364,31 +416,31 @@ static inline void setsub32(uint32_t a, uint32_t b) flags_op2 = b; flags_res = a - b; flags_op = FLAGS_SUB32; - - if (a < b) flags |= C_FLAG; - else flags &= ~C_FLAG; } static inline void setsub8nc(uint8_t a, uint8_t b) { + flags_rebuild_c(); flags_op1 = a; flags_op2 = b; flags_res = (a - b) & 0xff; - flags_op = FLAGS_SUB8; + flags_op = FLAGS_DEC8; } static inline void setsub16nc(uint16_t a, uint16_t b) { + flags_rebuild_c(); flags_op1 = a; flags_op2 = b; flags_res = (a - b) & 0xffff; - flags_op = FLAGS_SUB16; + flags_op = FLAGS_DEC16; } static inline void setsub32nc(uint32_t a, uint32_t b) { + flags_rebuild_c(); flags_op1 = a; flags_op2 = b; flags_res = a - b; - flags_op = FLAGS_SUB32; + flags_op = FLAGS_DEC32; } static inline void setadc8(uint8_t a, uint8_t b) diff --git a/src/x86_ops_arith.h b/src/x86_ops_arith.h index 2671e57..7e97b62 100644 --- a/src/x86_ops_arith.h +++ b/src/x86_ops_arith.h @@ -1,7 +1,7 @@ -#define OP_ARITH(name, operation, setflags, flagops) \ +#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ if (mod == 3) \ { \ @@ -23,7 +23,7 @@ } \ static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ if (mod == 3) \ { \ @@ -46,7 +46,7 @@ \ static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ if (mod == 3) \ { \ @@ -68,7 +68,7 @@ } \ static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ if (mod == 3) \ { \ @@ -91,7 +91,7 @@ \ static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ if (mod == 3) \ { \ @@ -113,7 +113,7 @@ } \ static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ if (mod == 3) \ { \ @@ -136,8 +136,8 @@ \ static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint8_t dst, src; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ dst = getr8(reg); \ src = geteab(); if (abrt) return 1; \ @@ -148,8 +148,8 @@ } \ static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint8_t dst, src; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ dst = getr8(reg); \ src = geteab(); if (abrt) return 1; \ @@ -161,8 +161,8 @@ \ static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint16_t dst, src; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ dst = regs[reg].w; \ src = geteaw(); if (abrt) return 1; \ @@ -173,8 +173,8 @@ } \ static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint16_t dst, src; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ dst = regs[reg].w; \ src = geteaw(); if (abrt) return 1; \ @@ -186,8 +186,8 @@ \ static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint32_t dst, src; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ dst = regs[reg].l; \ src = geteal(); if (abrt) return 1; \ @@ -198,8 +198,8 @@ } \ static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint32_t dst, src; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ dst = regs[reg].l; \ src = geteal(); if (abrt) return 1; \ @@ -211,9 +211,9 @@ \ static int op ## name ## _AL_imm(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint8_t dst = AL; \ uint8_t src = getbytef(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ setflags ## 8 flagops; \ AL = operation; \ CLOCK_CYCLES(timing_rr); \ @@ -222,9 +222,9 @@ \ static int op ## name ## _AX_imm(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint16_t dst = AX; \ uint16_t src = getwordf(); \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ setflags ## 16 flagops; \ AX = operation; \ CLOCK_CYCLES(timing_rr); \ @@ -233,22 +233,22 @@ \ static int op ## name ## _EAX_imm(uint32_t fetchdat) \ { \ - int tempc = CF_SET(); \ uint32_t dst = EAX; \ uint32_t src = getlong(); if (abrt) return 1; \ + if (gettempc) tempc = CF_SET() ? 1 : 0; \ setflags ## 32 flagops; \ EAX = operation; \ CLOCK_CYCLES(timing_rr); \ return 0; \ } -OP_ARITH(ADD, dst + src, setadd, (dst, src)) -OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src)) -OP_ARITH(SUB, dst - src, setsub, (dst, src)) -OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src)) -OP_ARITH(OR, dst | src, setznp, (dst | src)) -OP_ARITH(AND, dst & src, setznp, (dst & src)) -OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src)) +OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) +OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) +OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) +OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1) +OP_ARITH(OR, dst | src, setznp, (dst | src), 0) +OP_ARITH(AND, dst & src, setznp, (dst & src), 0) +OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) static int opCMP_b_rmw_a16(uint32_t fetchdat) { @@ -502,11 +502,13 @@ static int opTEST_EAX(uint32_t fetchdat) CLOCK_CYCLES((mod == 3) ? timing_rr : timing_mr); \ break; \ case 0x10: /*ADC ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ setea ## ea_width(dst + src + tempc); if (abrt) return 1; \ setadc ## flag_width(dst, src); \ CLOCK_CYCLES((mod == 3) ? timing_rr : timing_mr); \ break; \ case 0x18: /*SBB ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ setea ## ea_width(dst - (src + tempc)); if (abrt) return 1; \ setsbc ## flag_width(dst, src); \ CLOCK_CYCLES((mod == 3) ? timing_rr : timing_mr); \ diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index bc2fe76..17c29bc 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -67,26 +67,17 @@ case 0x20: case 0x30: /*SHL b,CL*/ \ seteab(temp << c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - if ((temp << (c - 1)) & 0x80) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x28: /*SHR b,CL*/ \ seteab(temp >> c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x38: /*SAR b,CL*/ \ - tempc = ((temp >> (c - 1)) & 1); \ - while (c > 0) \ - { \ - temp >>= 1; \ - if (temp & 0x40) temp |= 0x80; \ - c--; \ - } \ + temp = (int8_t)temp >> c; \ seteab(temp); if (abrt) return 1; \ set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - if (tempc) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ } \ @@ -161,26 +152,17 @@ case 0x20: case 0x30: /*SHL w, c*/ \ seteaw(temp << c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - if ((temp << (c - 1)) & 0x8000) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x28: /*SHR w, c*/ \ seteaw(temp >> c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x38: /*SAR w, c*/ \ - tempc = ((temp >> (c - 1)) & 1); \ - while (c > 0) \ - { \ - temp >>= 1; \ - if (temp & 0x4000) temp |= 0x8000; \ - c--; \ - } \ + temp = (int16_t)temp >> c; \ seteaw(temp); if (abrt) return 1; \ set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - if (tempc) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ } \ @@ -221,7 +203,7 @@ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x10: /*RCL l, c*/ \ - temp2 = flags & C_FLAG; \ + temp2 = CF_SET(); \ if (is486) CLOCK_CYCLES_ALWAYS(c); \ while (c > 0) \ { \ @@ -255,26 +237,17 @@ case 0x20: case 0x30: /*SHL l, c*/ \ seteal(temp << c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - if ((temp << (c - 1)) & 0x80000000) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x28: /*SHR l, c*/ \ seteal(temp >> c); if (abrt) return 1; \ set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - if ((temp >> (c - 1)) & 1) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ case 0x38: /*SAR l, c*/ \ - tempc = ((temp >> (c - 1)) & 1); \ - while (c > 0) \ - { \ - temp >>= 1; \ - if (temp & 0x40000000) temp |= 0x80000000; \ - c--; \ - } \ + temp = (int32_t)temp >> c; \ seteal(temp); if (abrt) return 1; \ set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - if (tempc) flags |= C_FLAG; \ CLOCK_CYCLES((mod == 3) ? 3 : 7); \ break; \ } \