jit_state: Split off CPSR.NZCV

This commit is contained in:
MerryMage 2017-12-09 15:42:47 +00:00
parent a3432102b8
commit 19a7fb8992
12 changed files with 182 additions and 94 deletions

View file

@ -117,6 +117,14 @@ void IREmitter::SetCpsr(const Value& value) {
Inst(Opcode::SetCpsr, {value});
}
void IREmitter::SetCpsrNZCV(const Value& value) {
Inst(Opcode::SetCpsrNZCV, {value});
}
void IREmitter::SetCpsrNZCVQ(const Value& value) {
Inst(Opcode::SetCpsrNZCVQ, {value});
}
Value IREmitter::GetCFlag() {
return Inst(Opcode::GetCFlag, {});
}
@ -149,6 +157,10 @@ void IREmitter::SetGEFlags(const Value& value) {
Inst(Opcode::SetGEFlags, {value});
}
void IREmitter::SetGEFlagsCompressed(const Value& value) {
Inst(Opcode::SetGEFlagsCompressed, {value});
}
Value IREmitter::GetFpscr() {
return Inst(Opcode::GetFpscr, {});
}

View file

@ -84,6 +84,8 @@ public:
Value GetCpsr();
void SetCpsr(const Value& value);
void SetCpsrNZCV(const Value& value);
void SetCpsrNZCVQ(const Value& value);
Value GetCFlag();
void SetNFlag(const Value& value);
void SetZFlag(const Value& value);
@ -92,6 +94,7 @@ public:
void OrQFlag(const Value& value);
Value GetGEFlags();
void SetGEFlags(const Value& value);
void SetGEFlagsCompressed(const Value& value);
Value GetFpscr();
void SetFpscr(const Value& new_fpscr);

View file

@ -112,12 +112,15 @@ bool Inst::ReadsFromCPSR() const {
bool Inst::WritesToCPSR() const {
switch (op) {
case Opcode::SetCpsr:
case Opcode::SetCpsrNZCV:
case Opcode::SetCpsrNZCVQ:
case Opcode::SetNFlag:
case Opcode::SetZFlag:
case Opcode::SetCFlag:
case Opcode::SetVFlag:
case Opcode::OrQFlag:
case Opcode::SetGEFlags:
case Opcode::SetGEFlagsCompressed:
return true;
default:

View file

@ -13,6 +13,8 @@ OPCODE(SetExtendedRegister32, T::Void, T::ExtRegRef, T::F32
OPCODE(SetExtendedRegister64, T::Void, T::ExtRegRef, T::F64 )
OPCODE(GetCpsr, T::U32, )
OPCODE(SetCpsr, T::Void, T::U32 )
OPCODE(SetCpsrNZCV, T::Void, T::U32 )
OPCODE(SetCpsrNZCVQ, T::Void, T::U32 )
OPCODE(GetNFlag, T::U1, )
OPCODE(SetNFlag, T::Void, T::U1 )
OPCODE(GetZFlag, T::U1, )
@ -24,6 +26,7 @@ OPCODE(SetVFlag, T::Void, T::U1
OPCODE(OrQFlag, T::Void, T::U1 )
OPCODE(GetGEFlags, T::U32, )
OPCODE(SetGEFlags, T::Void, T::U32 )
OPCODE(SetGEFlagsCompressed, T::Void, T::U32 )
OPCODE(BXWritePC, T::Void, T::U32 )
OPCODE(CallSupervisor, T::Void, T::U32 )
OPCODE(GetFpscr, T::U32, )

View file

@ -92,9 +92,8 @@ bool ArmTranslatorVisitor::arm_MRC(Cond cond, size_t opc1, CoprocReg CRn, Reg t,
if (t != Reg::PC) {
ir.SetRegister(t, word);
} else {
auto old_cpsr = ir.And(ir.GetCpsr(), ir.Imm32(0x0FFFFFFF));
auto new_cpsr_nzcv = ir.And(word, ir.Imm32(0xF0000000));
ir.SetCpsr(ir.Or(old_cpsr, new_cpsr_nzcv));
ir.SetCpsrNZCV(new_cpsr_nzcv);
}
}
return true;

View file

@ -6,6 +6,8 @@
#include "translate_arm.h"
#include "common/bit_util.h"
namespace Dynarmic {
namespace Arm {
@ -30,14 +32,12 @@ bool ArmTranslatorVisitor::arm_MSR_imm(Cond cond, int mask, int rotate, Imm8 imm
ASSERT_MSG(write_nzcvq || write_g, "Decode error");
// MSR <spec_reg>, #<imm32>
if (ConditionPassed(cond)) {
u32 cpsr_mask = 0;
if (write_nzcvq)
cpsr_mask |= 0xF8000000;
if (write_g)
cpsr_mask |= 0x000F0000;
auto old_cpsr = ir.And(ir.GetCpsr(), ir.Imm32(~cpsr_mask));
auto new_cpsr = ir.Imm32(imm32 & cpsr_mask);
ir.SetCpsr(ir.Or(old_cpsr, new_cpsr));
if (write_nzcvq) {
ir.SetCpsrNZCVQ(ir.Imm32(imm32 & 0xF8000000));
}
if (write_g) {
ir.SetGEFlagsCompressed(ir.Imm32(imm32 & 0x000F0000));
}
}
return true;
}
@ -51,14 +51,13 @@ bool ArmTranslatorVisitor::arm_MSR_reg(Cond cond, int mask, Reg n) {
return UnpredictableInstruction();
// MSR <spec_reg>, #<imm32>
if (ConditionPassed(cond)) {
u32 cpsr_mask = 0;
if (write_nzcvq)
cpsr_mask |= 0xF8000000;
if (write_g)
cpsr_mask |= 0x000F0000;
auto old_cpsr = ir.And(ir.GetCpsr(), ir.Imm32(~cpsr_mask));
auto new_cpsr = ir.And(ir.GetRegister(n), ir.Imm32(cpsr_mask));
ir.SetCpsr(ir.Or(old_cpsr, new_cpsr));
auto value = ir.GetRegister(n);
if (write_nzcvq){
ir.SetCpsrNZCVQ(ir.And(value, ir.Imm32(0xF8000000)));
}
if (write_g){
ir.SetGEFlagsCompressed(ir.And(value, ir.Imm32(0x000F0000)));
}
}
return true;
}

View file

@ -543,8 +543,7 @@ bool ArmTranslatorVisitor::vfp2_VMRS(Cond cond, Reg t) {
if (t == Reg::R15) {
// This encodes ASPR_nzcv access
auto nzcv = ir.GetFpscrNZCV();
auto old_cpsr = ir.And(ir.GetCpsr(), ir.Imm32(0x0FFFFFFF));
ir.SetCpsr(ir.Or(nzcv, old_cpsr));
ir.SetCpsrNZCV(nzcv);
} else {
ir.SetRegister(t, ir.GetFpscr());
}