mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-01 04:04:30 +01:00
jit_state: Split off CPSR.NZCV
This commit is contained in:
parent
a3432102b8
commit
19a7fb8992
12 changed files with 182 additions and 94 deletions
|
|
@ -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, {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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, )
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue