emit_x64: Inline nzcv computation into EmitFPCompare32 and EmitFPCompare64

This commit is contained in:
MerryMage 2016-12-04 11:43:31 +00:00
parent 52fdec5892
commit 25f21b5371

View file

@ -1772,22 +1772,27 @@ void EmitX64::EmitFPSub64(IR::Block& block, IR::Inst* inst) {
FPThreeOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::subsd); FPThreeOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::subsd);
} }
static void SetFpscrNzcvFromLahf(JitState* jit_state, u8 lahf) { static void SetFpscrNzcvFromFlags(BlockOfCode* code, RegAlloc& reg_alloc) {
switch (lahf) { reg_alloc.ScratchGpr({HostLoc::RAX}); // lahf requires use of ah
case 0b01000111: Xbyak::Reg32 nzcv_imm = reg_alloc.ScratchGpr().cvt32();
jit_state->FPSCR_nzcv = 0x30000000; Xbyak::Reg32 nzcv = reg_alloc.ScratchGpr().cvt32();
return;
case 0b00000010: using namespace Xbyak::util;
jit_state->FPSCR_nzcv = 0x20000000;
return; code->lahf();
case 0b00000011: code->mov(nzcv_imm, 0x30000000);
jit_state->FPSCR_nzcv = 0x80000000; code->cmp(ah, 0b01000111);
return; code->cmove(nzcv, nzcv_imm);
case 0b01000010: code->mov(nzcv_imm, 0x20000000);
jit_state->FPSCR_nzcv = 0x60000000; code->cmp(ah, 0b00000010);
return; code->cmove(nzcv, nzcv_imm);
} code->mov(nzcv_imm, 0x80000000);
ASSERT_MSG(false, "<internal error>"); code->cmp(ah, 0b00000011);
code->cmove(nzcv, nzcv_imm);
code->mov(nzcv_imm, 0x60000000);
code->cmp(ah, 0b01000010);
code->cmove(nzcv, nzcv_imm);
code->mov(dword[r15 + offsetof(JitState, FPSCR_nzcv)], nzcv);
} }
void EmitX64::EmitFPCompare32(IR::Block& block, IR::Inst* inst) { void EmitX64::EmitFPCompare32(IR::Block& block, IR::Inst* inst) {
@ -1804,13 +1809,7 @@ void EmitX64::EmitFPCompare32(IR::Block& block, IR::Inst* inst) {
code->comiss(reg_a, reg_b); code->comiss(reg_a, reg_b);
} }
reg_alloc.EndOfAllocScope(); SetFpscrNzcvFromFlags(code, reg_alloc);
reg_alloc.HostCall();
code->lahf();
code->mov(code->ABI_PARAM1, code->r15);
code->mov(code->ABI_PARAM2.cvt8(), code->ah);
code->CallFunction(&SetFpscrNzcvFromLahf);
} }
void EmitX64::EmitFPCompare64(IR::Block& block, IR::Inst* inst) { void EmitX64::EmitFPCompare64(IR::Block& block, IR::Inst* inst) {
@ -1827,13 +1826,7 @@ void EmitX64::EmitFPCompare64(IR::Block& block, IR::Inst* inst) {
code->comisd(reg_a, reg_b); code->comisd(reg_a, reg_b);
} }
reg_alloc.EndOfAllocScope(); SetFpscrNzcvFromFlags(code, reg_alloc);
reg_alloc.HostCall();
code->lahf();
code->mov(code->ABI_PARAM1, code->r15);
code->mov(code->ABI_PARAM2.cvt8(), code->ah);
code->CallFunction(&SetFpscrNzcvFromLahf);
} }
void EmitX64::EmitFPSingleToDouble(IR::Block& block, IR::Inst* inst) { void EmitX64::EmitFPSingleToDouble(IR::Block& block, IR::Inst* inst) {