mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-12 19:46:28 +00:00
A64: Implement system registers FPCR and FPSR
This commit is contained in:
@@ -66,7 +66,7 @@ INST(DSB, "DSB", "11010
|
||||
INST(DMB, "DMB", "11010101000000110011MMMM10111111")
|
||||
//INST(ISB, "ISB", "11010101000000110011MMMM11011111")
|
||||
//INST(SYS, "SYS", "1101010100001oooNNNNMMMMooottttt")
|
||||
//INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt")
|
||||
INST(MSR_reg, "MSR (register)", "110101010001poooNNNNMMMMooottttt")
|
||||
//INST(SYSL, "SYSL", "1101010100101oooNNNNMMMMooottttt")
|
||||
INST(MRS, "MRS", "110101010011poooNNNNMMMMooottttt")
|
||||
|
||||
|
||||
@@ -166,6 +166,14 @@ IR::U64 IREmitter::GetSP() {
|
||||
return Inst<IR::U64>(Opcode::A64GetSP);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetFPCR() {
|
||||
return Inst<IR::U32>(Opcode::A64GetFPCR);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetFPSR() {
|
||||
return Inst<IR::U32>(Opcode::A64GetFPSR);
|
||||
}
|
||||
|
||||
void IREmitter::SetW(const Reg reg, const IR::U32& value) {
|
||||
if (reg == Reg::ZR)
|
||||
return;
|
||||
@@ -194,6 +202,14 @@ void IREmitter::SetSP(const IR::U64& value) {
|
||||
Inst(Opcode::A64SetSP, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetFPCR(const IR::U32& value) {
|
||||
Inst(Opcode::A64SetFPCR, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetFPSR(const IR::U32& value) {
|
||||
Inst(Opcode::A64SetFPSR, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetPC(const IR::U64& value) {
|
||||
Inst(Opcode::A64SetPC, value);
|
||||
}
|
||||
|
||||
@@ -73,12 +73,16 @@ public:
|
||||
IR::U128 GetD(Vec source_vec);
|
||||
IR::U128 GetQ(Vec source_vec);
|
||||
IR::U64 GetSP();
|
||||
IR::U32 GetFPCR();
|
||||
IR::U32 GetFPSR();
|
||||
void SetW(Reg dest_reg, const IR::U32& value);
|
||||
void SetX(Reg dest_reg, const IR::U64& value);
|
||||
void SetS(Vec dest_vec, const IR::U128& value);
|
||||
void SetD(Vec dest_vec, const IR::U128& value);
|
||||
void SetQ(Vec dest_vec, const IR::U128& value);
|
||||
void SetSP(const IR::U64& value);
|
||||
void SetFPCR(const IR::U32& value);
|
||||
void SetFPSR(const IR::U32& value);
|
||||
void SetPC(const IR::U64& value);
|
||||
};
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ struct TranslatorVisitor final {
|
||||
bool DMB(Imm<4> CRm);
|
||||
bool ISB(Imm<4> CRm);
|
||||
bool SYS(Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
|
||||
bool MSR_reg(bool o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
|
||||
bool MSR_reg(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
|
||||
bool SYSL(Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
|
||||
bool MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt);
|
||||
|
||||
|
||||
@@ -51,6 +51,20 @@ bool TranslatorVisitor::DMB(Imm<4> /*CRm*/) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::MSR_reg(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt) {
|
||||
const size_t sys_reg = concatenate(Imm<1>{1}, o0, op1, CRn, CRm, op2).ZeroExtend<size_t>();
|
||||
switch (sys_reg) {
|
||||
case 0b11'011'0100'0100'000: // FPCR
|
||||
ir.SetFPCR(X(32, Rt));
|
||||
ir.SetTerm(IR::Term::ReturnToDispatch{});
|
||||
return false;
|
||||
case 0b11'011'0100'0100'001: // FPSR
|
||||
ir.SetFPSR(X(32, Rt));
|
||||
return true;
|
||||
}
|
||||
return InterpretThisInstruction();
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3> op2, Reg Rt) {
|
||||
const size_t sys_reg = concatenate(Imm<1>{1}, o0, op1, CRn, CRm, op2).ZeroExtend<size_t>();
|
||||
switch (sys_reg) {
|
||||
@@ -66,6 +80,12 @@ bool TranslatorVisitor::MRS(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, Imm<3
|
||||
case 0b11'011'1110'0000'001: // CNTPCT_EL0
|
||||
X(64, Rt, ir.GetCNTPCT());
|
||||
return true;
|
||||
case 0b11'011'0100'0100'000: // FPCR
|
||||
X(32, Rt, ir.GetFPCR());
|
||||
return true;
|
||||
case 0b11'011'0100'0100'001: // FPSR
|
||||
X(32, Rt, ir.GetFPSR());
|
||||
return true;
|
||||
}
|
||||
return InterpretThisInstruction();
|
||||
}
|
||||
|
||||
@@ -194,6 +194,8 @@ bool Inst::ReadsFromFPSCR() const {
|
||||
switch (op) {
|
||||
case Opcode::A32GetFpscr:
|
||||
case Opcode::A32GetFpscrNZCV:
|
||||
case Opcode::A64GetFPCR:
|
||||
case Opcode::A64GetFPSR:
|
||||
case Opcode::FPAbs32:
|
||||
case Opcode::FPAbs64:
|
||||
case Opcode::FPAdd32:
|
||||
@@ -221,6 +223,8 @@ bool Inst::WritesToFPSCR() const {
|
||||
switch (op) {
|
||||
case Opcode::A32SetFpscr:
|
||||
case Opcode::A32SetFpscrNZCV:
|
||||
case Opcode::A64SetFPCR:
|
||||
case Opcode::A64SetFPSR:
|
||||
case Opcode::FPAbs32:
|
||||
case Opcode::FPAbs64:
|
||||
case Opcode::FPAdd32:
|
||||
|
||||
@@ -47,6 +47,8 @@ A64OPC(GetS, T::U128, T::A64Vec
|
||||
A64OPC(GetD, T::U128, T::A64Vec )
|
||||
A64OPC(GetQ, T::U128, T::A64Vec )
|
||||
A64OPC(GetSP, T::U64, )
|
||||
A64OPC(GetFPCR, T::U32, )
|
||||
A64OPC(GetFPSR, T::U32, )
|
||||
A64OPC(SetW, T::Void, T::A64Reg, T::U32 )
|
||||
A64OPC(SetX, T::Void, T::A64Reg, T::U64 )
|
||||
//A64OPC(SetB, T::Void, T::A64Vec, T::U8 )
|
||||
@@ -55,6 +57,8 @@ A64OPC(SetS, T::Void, T::A64Vec, T::U128
|
||||
A64OPC(SetD, T::Void, T::A64Vec, T::U128 )
|
||||
A64OPC(SetQ, T::Void, T::A64Vec, T::U128 )
|
||||
A64OPC(SetSP, T::Void, T::U64 )
|
||||
A64OPC(SetFPCR, T::Void, T::U32 )
|
||||
A64OPC(SetFPSR, T::Void, T::U32 )
|
||||
A64OPC(SetPC, T::Void, T::U64 )
|
||||
A64OPC(CallSupervisor, T::Void, T::U32 )
|
||||
A64OPC(ExceptionRaised, T::Void, T::U64, T::U64 )
|
||||
|
||||
Reference in New Issue
Block a user