block_of_code: Extract flag loading into a function
LoadRequiredFlagsForCondFromRax
This commit is contained in:
parent
d7bd5bb7a7
commit
a38966a874
4 changed files with 72 additions and 72 deletions
|
@ -393,6 +393,44 @@ void BlockOfCode::LookupBlock() {
|
|||
cb.LookupBlock->EmitCall(*this);
|
||||
}
|
||||
|
||||
void BlockOfCode::LoadRequiredFlagsForCondFromRax(IR::Cond cond) {
|
||||
// sahf restores SF, ZF, CF
|
||||
// add al, 0x7F restores OF
|
||||
|
||||
switch (cond) {
|
||||
case IR::Cond::EQ: // z
|
||||
case IR::Cond::NE: // !z
|
||||
case IR::Cond::CS: // c
|
||||
case IR::Cond::CC: // !c
|
||||
case IR::Cond::MI: // n
|
||||
case IR::Cond::PL: // !n
|
||||
sahf();
|
||||
break;
|
||||
case IR::Cond::VS: // v
|
||||
case IR::Cond::VC: // !v
|
||||
cmp(al, 0x81);
|
||||
break;
|
||||
case IR::Cond::HI: // c & !z
|
||||
case IR::Cond::LS: // !c | z
|
||||
sahf();
|
||||
cmc();
|
||||
break;
|
||||
case IR::Cond::GE: // n == v
|
||||
case IR::Cond::LT: // n != v
|
||||
case IR::Cond::GT: // !z & (n == v)
|
||||
case IR::Cond::LE: // z | (n != v)
|
||||
cmp(al, 0x81);
|
||||
sahf();
|
||||
break;
|
||||
case IR::Cond::AL:
|
||||
case IR::Cond::NV:
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(false, "Unknown cond {}", static_cast<size_t>(cond));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Xbyak::Address BlockOfCode::MConst(const Xbyak::AddressFrame& frame, u64 lower, u64 upper) {
|
||||
return constant_pool.GetConstant(frame, lower, upper);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||
#include "dynarmic/common/cast_util.h"
|
||||
#include "dynarmic/interface/halt_reason.h"
|
||||
#include "dynarmic/ir/cond.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
|
@ -74,6 +75,9 @@ public:
|
|||
/// @note this clobbers ABI caller-save registers
|
||||
void LookupBlock();
|
||||
|
||||
/// Code emitter: Load required flags for conditional cond from rax into host rflags
|
||||
void LoadRequiredFlagsForCondFromRax(IR::Cond cond);
|
||||
|
||||
/// Code emitter: Calls the function
|
||||
template<typename FunctionPointer>
|
||||
void CallFunction(FunctionPointer fn) {
|
||||
|
|
|
@ -244,70 +244,49 @@ Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {
|
|||
|
||||
code.mov(eax, dword[r15 + code.GetJitStateInfo().offsetof_cpsr_nzcv]);
|
||||
|
||||
// sahf restores SF, ZF, CF
|
||||
// add al, 0x7F restores OF
|
||||
code.LoadRequiredFlagsForCondFromRax(cond);
|
||||
|
||||
switch (cond) {
|
||||
case IR::Cond::EQ: // z
|
||||
code.sahf();
|
||||
case IR::Cond::EQ:
|
||||
code.jz(pass);
|
||||
break;
|
||||
case IR::Cond::NE: //! z
|
||||
code.sahf();
|
||||
case IR::Cond::NE:
|
||||
code.jnz(pass);
|
||||
break;
|
||||
case IR::Cond::CS: // c
|
||||
code.sahf();
|
||||
case IR::Cond::CS:
|
||||
code.jc(pass);
|
||||
break;
|
||||
case IR::Cond::CC: //! c
|
||||
code.sahf();
|
||||
case IR::Cond::CC:
|
||||
code.jnc(pass);
|
||||
break;
|
||||
case IR::Cond::MI: // n
|
||||
code.sahf();
|
||||
case IR::Cond::MI:
|
||||
code.js(pass);
|
||||
break;
|
||||
case IR::Cond::PL: //! n
|
||||
code.sahf();
|
||||
case IR::Cond::PL:
|
||||
code.jns(pass);
|
||||
break;
|
||||
case IR::Cond::VS: // v
|
||||
code.cmp(al, 0x81);
|
||||
case IR::Cond::VS:
|
||||
code.jo(pass);
|
||||
break;
|
||||
case IR::Cond::VC: //! v
|
||||
code.cmp(al, 0x81);
|
||||
case IR::Cond::VC:
|
||||
code.jno(pass);
|
||||
break;
|
||||
case IR::Cond::HI: // c & !z
|
||||
code.sahf();
|
||||
code.cmc();
|
||||
case IR::Cond::HI:
|
||||
code.ja(pass);
|
||||
break;
|
||||
case IR::Cond::LS: //! c | z
|
||||
code.sahf();
|
||||
code.cmc();
|
||||
case IR::Cond::LS:
|
||||
code.jna(pass);
|
||||
break;
|
||||
case IR::Cond::GE: // n == v
|
||||
code.cmp(al, 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::GE:
|
||||
code.jge(pass);
|
||||
break;
|
||||
case IR::Cond::LT: // n != v
|
||||
code.cmp(al, 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::LT:
|
||||
code.jl(pass);
|
||||
break;
|
||||
case IR::Cond::GT: // !z & (n == v)
|
||||
code.cmp(al, 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::GT:
|
||||
code.jg(pass);
|
||||
break;
|
||||
case IR::Cond::LE: // z | (n != v)
|
||||
code.cmp(al, 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::LE:
|
||||
code.jle(pass);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -143,70 +143,49 @@ static void EmitConditionalSelect(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
|
||||
code.mov(nzcv, dword[r15 + code.GetJitStateInfo().offsetof_cpsr_nzcv]);
|
||||
|
||||
// sahf restores SF, ZF, CF
|
||||
// add al, 0x7F restores OF
|
||||
code.LoadRequiredFlagsForCondFromRax(args[0].GetImmediateCond());
|
||||
|
||||
switch (args[0].GetImmediateCond()) {
|
||||
case IR::Cond::EQ: // z
|
||||
code.sahf();
|
||||
case IR::Cond::EQ:
|
||||
code.cmovz(else_, then_);
|
||||
break;
|
||||
case IR::Cond::NE: //! z
|
||||
code.sahf();
|
||||
case IR::Cond::NE:
|
||||
code.cmovnz(else_, then_);
|
||||
break;
|
||||
case IR::Cond::CS: // c
|
||||
code.sahf();
|
||||
case IR::Cond::CS:
|
||||
code.cmovc(else_, then_);
|
||||
break;
|
||||
case IR::Cond::CC: //! c
|
||||
code.sahf();
|
||||
case IR::Cond::CC:
|
||||
code.cmovnc(else_, then_);
|
||||
break;
|
||||
case IR::Cond::MI: // n
|
||||
code.sahf();
|
||||
case IR::Cond::MI:
|
||||
code.cmovs(else_, then_);
|
||||
break;
|
||||
case IR::Cond::PL: //! n
|
||||
code.sahf();
|
||||
case IR::Cond::PL:
|
||||
code.cmovns(else_, then_);
|
||||
break;
|
||||
case IR::Cond::VS: // v
|
||||
code.cmp(nzcv.cvt8(), 0x81);
|
||||
case IR::Cond::VS:
|
||||
code.cmovo(else_, then_);
|
||||
break;
|
||||
case IR::Cond::VC: //! v
|
||||
code.cmp(nzcv.cvt8(), 0x81);
|
||||
case IR::Cond::VC:
|
||||
code.cmovno(else_, then_);
|
||||
break;
|
||||
case IR::Cond::HI: // c & !z
|
||||
code.sahf();
|
||||
code.cmc();
|
||||
case IR::Cond::HI:
|
||||
code.cmova(else_, then_);
|
||||
break;
|
||||
case IR::Cond::LS: //! c | z
|
||||
code.sahf();
|
||||
code.cmc();
|
||||
case IR::Cond::LS:
|
||||
code.cmovna(else_, then_);
|
||||
break;
|
||||
case IR::Cond::GE: // n == v
|
||||
code.cmp(nzcv.cvt8(), 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::GE:
|
||||
code.cmovge(else_, then_);
|
||||
break;
|
||||
case IR::Cond::LT: // n != v
|
||||
code.cmp(nzcv.cvt8(), 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::LT:
|
||||
code.cmovl(else_, then_);
|
||||
break;
|
||||
case IR::Cond::GT: // !z & (n == v)
|
||||
code.cmp(nzcv.cvt8(), 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::GT:
|
||||
code.cmovg(else_, then_);
|
||||
break;
|
||||
case IR::Cond::LE: // z | (n != v)
|
||||
code.cmp(nzcv.cvt8(), 0x81);
|
||||
code.sahf();
|
||||
case IR::Cond::LE:
|
||||
code.cmovle(else_, then_);
|
||||
break;
|
||||
case IR::Cond::AL:
|
||||
|
|
Loading…
Reference in a new issue