jit_state: Hide cpsr implementation

This commit is contained in:
MerryMage 2017-12-02 13:55:04 +00:00
parent a4e85ad565
commit 6adc554b53
8 changed files with 87 additions and 37 deletions

View file

@ -62,7 +62,7 @@ static Xbyak::Address MJitStateExtReg(Arm::ExtReg reg) {
static Xbyak::Address MJitStateCpsr() {
using namespace Xbyak::util;
return dword[r15 + offsetof(JitState, Cpsr)];
return dword[r15 + offsetof(JitState, CPSR)];
}
static void EraseInstruction(IR::Block& block, IR::Inst* inst) {
@ -196,16 +196,25 @@ void EmitX64::EmitSetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Ins
code->movsd(MJitStateExtReg(reg), source);
}
static u32 GetCpsrImpl(JitState* jit_state) {
return jit_state->Cpsr();
}
void EmitX64::EmitGetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) {
Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32();
code->mov(result, MJitStateCpsr());
reg_alloc.DefineValue(inst, result);
reg_alloc.HostCall(inst);
code->mov(code->ABI_PARAM1, code->r15);
code->CallFunction(&GetCpsrImpl);
}
static void SetCpsrImpl(u32 value, JitState* jit_state) {
jit_state->SetCpsr(value);
}
void EmitX64::EmitSetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) {
auto args = reg_alloc.GetArgumentInfo(inst);
Xbyak::Reg32 arg = reg_alloc.UseGpr(args[0]).cvt32();
code->mov(MJitStateCpsr(), arg);
reg_alloc.HostCall(nullptr, args[0]);
code->mov(code->ABI_PARAM2, code->r15);
code->CallFunction(&SetCpsrImpl);
}
void EmitX64::EmitGetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) {
@ -404,9 +413,9 @@ void EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) {
} else {
using Xbyak::util::ptr;
Xbyak::Reg64 new_pc = reg_alloc.UseScratchGpr(arg);
Xbyak::Reg64 tmp1 = reg_alloc.ScratchGpr();
Xbyak::Reg64 tmp2 = reg_alloc.ScratchGpr();
Xbyak::Reg32 new_pc = reg_alloc.UseScratchGpr(arg).cvt32();
Xbyak::Reg32 tmp1 = reg_alloc.ScratchGpr().cvt32();
Xbyak::Reg32 tmp2 = reg_alloc.ScratchGpr().cvt32();
code->mov(tmp1, MJitStateCpsr());
code->mov(tmp2, tmp1);
@ -415,7 +424,7 @@ void EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) {
code->test(new_pc, u32(1));
code->cmove(tmp1, tmp2); // CPSR.T = pc & 1
code->mov(MJitStateCpsr(), tmp1);
code->lea(tmp2, ptr[new_pc + new_pc * 1]);
code->lea(tmp2, ptr[new_pc.cvt64() + new_pc.cvt64() * 1]);
code->or_(tmp2, u32(0xFFFFFFFC)); // tmp2 = pc & 1 ? 0xFFFFFFFE : 0xFFFFFFFC
code->and_(new_pc, tmp2);
code->mov(MJitStateReg(Arm::Reg::PC), new_pc);

View file

@ -127,7 +127,7 @@ private:
JitState& jit_state = this_.jit_state;
u32 pc = jit_state.Reg[15];
Arm::PSR cpsr{jit_state.Cpsr};
Arm::PSR cpsr{jit_state.Cpsr()};
Arm::FPSCR fpscr{jit_state.FPSCR_mode};
IR::LocationDescriptor descriptor{pc, cpsr, fpscr};
@ -205,19 +205,19 @@ const std::array<u32, 64>& Jit::ExtRegs() const {
return impl->jit_state.ExtReg;
}
u32& Jit::Cpsr() {
return impl->jit_state.Cpsr;
u32 Jit::Cpsr() const {
return impl->jit_state.Cpsr();
}
u32 Jit::Cpsr() const {
return impl->jit_state.Cpsr;
void Jit::SetCpsr(u32 value) {
return impl->jit_state.SetCpsr(value);
}
u32 Jit::Fpscr() const {
return impl->jit_state.Fpscr();
}
void Jit::SetFpscr(u32 value) const {
void Jit::SetFpscr(u32 value) {
return impl->jit_state.SetFpscr(value);
}

View file

@ -14,6 +14,44 @@
namespace Dynarmic {
namespace BackendX64 {
/**
* CPSR Bits
* =========
*
* ARM CPSR flags
* --------------
* N bit 31 Negative flag
* Z bit 30 Zero flag
* C bit 29 Carry flag
* V bit 28 oVerflow flag
* Q bit 27 Saturation flag
* J bit 24 Jazelle instruction set flag
* GE bits 16-19 Greater than or Equal flags
* E bit 9 Data Endianness flag
* A bit 8 Disable imprecise Aborts
* I bit 7 Disable IRQ interrupts
* F bit 6 Disable FIQ interrupts
* T bit 5 Thumb instruction set flag
* M bits 0-4 Processor Mode bits
*
* x64 LAHF+SETO flags
* -------------------
* SF bit 15 Sign flag
* ZF bit 14 Zero flag
* AF bit 12 Auxiliary flag
* PF bit 10 Parity flag
* CF bit 8 Carry flag
* OF bit 0 Overflow flag
*/
u32 JitState::Cpsr() const {
return CPSR;
}
void JitState::SetCpsr(u32 cpsr) {
CPSR = cpsr;
}
void JitState::ResetRSB() {
rsb_location_descriptors.fill(0xFFFFFFFFFFFFFFFFull);
rsb_codeptrs.fill(0);

View file

@ -25,10 +25,13 @@ constexpr size_t SpillCount = 64;
struct JitState {
JitState() { ResetRSB(); }
u32 Cpsr = 0;
std::array<u32, 16> Reg{}; // Current register file.
// TODO: Mode-specific register sets unimplemented.
u32 CPSR = 0;
u32 Cpsr() const;
void SetCpsr(u32 cpsr);
alignas(u64) std::array<u32, 64> ExtReg{}; // Extension registers.
std::array<u64, SpillCount> Spill{}; // Spill.