block_of_code: Extract flag loading into a function

LoadRequiredFlagsForCondFromRax
This commit is contained in:
Merry 2022-08-05 21:43:37 +01:00
parent d7bd5bb7a7
commit a38966a874
4 changed files with 72 additions and 72 deletions

View file

@ -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);
}

View file

@ -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) {

View file

@ -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:

View file

@ -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: