A32/IR: Add SetVector and GetVector

This commit is contained in:
MerryMage 2020-05-28 20:39:19 +01:00
parent e85a08ec34
commit 07108246cf
9 changed files with 141 additions and 27 deletions

View file

@ -41,6 +41,11 @@ IR::U32U64 IREmitter::GetExtendedRegister(ExtReg reg) {
ASSERT_FALSE("Invalid reg.");
}
IR::U128 IREmitter::GetVector(ExtReg reg) {
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
return Inst<IR::U128>(Opcode::A32GetVector, IR::Value(reg));
}
void IREmitter::SetRegister(const Reg reg, const IR::U32& value) {
ASSERT(reg != A32::Reg::PC);
Inst(Opcode::A32SetRegister, IR::Value(reg), value);
@ -56,6 +61,11 @@ void IREmitter::SetExtendedRegister(const ExtReg reg, const IR::U32U64& value) {
}
}
void IREmitter::SetVector(ExtReg reg, const IR::U128& value) {
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
Inst(Opcode::A32SetVector, IR::Value(reg), value);
}
void IREmitter::ALUWritePC(const IR::U32& value) {
// This behaviour is ARM version-dependent.
// The below implementation is for ARMv6k

View file

@ -33,8 +33,10 @@ public:
IR::U32 GetRegister(Reg source_reg);
IR::U32U64 GetExtendedRegister(ExtReg source_reg);
IR::U128 GetVector(ExtReg source_reg);
void SetRegister(Reg dest_reg, const IR::U32& value);
void SetExtendedRegister(ExtReg dest_reg, const IR::U32U64& value);
void SetVector(ExtReg dest_reg, const IR::U128& value);
void ALUWritePC(const IR::U32& value);
void BranchWritePC(const IR::U32& value);

View file

@ -38,6 +38,9 @@ const char* ExtRegToString(ExtReg reg) {
"d9", "d10", "d11", "d12", "d13", "d14", "d15", "d16",
"d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
"d25", "d26", "d27", "d28", "d29", "d30", "d31",
"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8",
"q9", "q10", "q11", "q12", "q13", "q14", "q15", "q16",
};
return reg_strs.at(static_cast<size_t>(reg));
}

View file

@ -36,6 +36,8 @@ enum class ExtReg {
D8, D9, D10, D11, D12, D13, D14, D15,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31,
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7,
Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15,
};
using RegList = u16;
@ -73,6 +75,10 @@ constexpr bool IsDoubleExtReg(ExtReg reg) {
return reg >= ExtReg::D0 && reg <= ExtReg::D31;
}
constexpr bool IsQuadExtReg(ExtReg reg) {
return reg >= ExtReg::Q0 && reg <= ExtReg::Q15;
}
inline size_t RegNumber(Reg reg) {
ASSERT(reg != Reg::INVALID_REG);
return static_cast<size_t>(reg);
@ -87,6 +93,10 @@ inline size_t RegNumber(ExtReg reg) {
return static_cast<size_t>(reg) - static_cast<size_t>(ExtReg::D0);
}
if (IsQuadExtReg(reg)) {
return static_cast<size_t>(reg) - static_cast<size_t>(ExtReg::Q0);
}
ASSERT_FALSE("Invalid extended register");
}
@ -101,11 +111,16 @@ inline ExtReg operator+(ExtReg reg, size_t number) {
const auto new_reg = static_cast<ExtReg>(static_cast<size_t>(reg) + number);
ASSERT((IsSingleExtReg(reg) && IsSingleExtReg(new_reg)) ||
(IsDoubleExtReg(reg) && IsDoubleExtReg(new_reg)));
(IsDoubleExtReg(reg) && IsDoubleExtReg(new_reg)) ||
(IsQuadExtReg(reg) && IsQuadExtReg(new_reg)));
return new_reg;
}
inline ExtReg ToExtRegQ(size_t base, bool bit) {
return ExtReg::Q0 + ((base >> 1) + (bit ? 8 : 0));
}
inline ExtReg ToExtRegD(size_t base, bool bit) {
return ExtReg::D0 + (base + (bit ? 16 : 0));
}
@ -115,11 +130,11 @@ inline ExtReg ToExtRegS(size_t base, bool bit) {
}
inline ExtReg ToExtReg(bool sz, size_t base, bool bit) {
if (sz) {
return ToExtRegD(base, bit);
} else {
return ToExtRegS(base, bit);
}
return sz ? ToExtRegD(base, bit) : ToExtRegS(base, bit);
}
inline ExtReg ToVector(bool Q, size_t base, bool bit) {
return Q ? ToExtRegQ(base, bit) : ToExtRegD(base, bit);
}
} // namespace Dynarmic::A32

View file

@ -198,6 +198,7 @@ bool Inst::ReadsFromCoreRegister() const {
case Opcode::A32GetRegister:
case Opcode::A32GetExtendedRegister32:
case Opcode::A32GetExtendedRegister64:
case Opcode::A32GetVector:
case Opcode::A64GetW:
case Opcode::A64GetX:
case Opcode::A64GetS:
@ -216,6 +217,7 @@ bool Inst::WritesToCoreRegister() const {
case Opcode::A32SetRegister:
case Opcode::A32SetExtendedRegister32:
case Opcode::A32SetExtendedRegister64:
case Opcode::A32SetVector:
case Opcode::A32BXWritePC:
case Opcode::A64SetW:
case Opcode::A64SetX:

View file

@ -9,9 +9,11 @@ A32OPC(SetCheckBit, Void, U1
A32OPC(GetRegister, U32, A32Reg )
A32OPC(GetExtendedRegister32, U32, A32ExtReg )
A32OPC(GetExtendedRegister64, U64, A32ExtReg )
A32OPC(GetVector, U128, A32ExtReg )
A32OPC(SetRegister, Void, A32Reg, U32 )
A32OPC(SetExtendedRegister32, Void, A32ExtReg, U32 )
A32OPC(SetExtendedRegister64, Void, A32ExtReg, U64 )
A32OPC(SetVector, Void, A32ExtReg, U128 )
A32OPC(GetCpsr, U32, )
A32OPC(SetCpsr, Void, U32 )
A32OPC(SetCpsrNZCV, Void, U32 )