mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-05 14:08:17 +01:00
VFP: Implement {Get,Set}ExtendedRegister{32,64}
This commit is contained in:
parent
d31bbd6d14
commit
640ce48baa
15 changed files with 262 additions and 16 deletions
|
|
@ -51,6 +51,17 @@ inline const char* RegToString(Reg reg) {
|
|||
return reg_strs.at(static_cast<size_t>(reg));
|
||||
}
|
||||
|
||||
enum class ExtReg {
|
||||
S0, S1, S2, S3, S4, S5, S6, S7,
|
||||
S8, S9, S10, S11, S12, S13, S14, S15,
|
||||
S16, S17, S18, S19, S20, S21, S22, S23,
|
||||
S24, S25, S26, S27, S28, S29, S30, S31,
|
||||
D0, D1, D2, D3, D4, D5, D6, D7,
|
||||
D8, D9, D10, D11, D12, D13, D14, D15,
|
||||
D16, D17, D18, D19, D20, D21, D22, D23,
|
||||
D24, D25, D26, D27, D28, D29, D30, D31,
|
||||
};
|
||||
|
||||
using Imm3 = u32;
|
||||
using Imm4 = u32;
|
||||
using Imm5 = u32;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,11 @@ Arm::Reg Value::GetRegRef() const {
|
|||
return inner.imm_regref;
|
||||
}
|
||||
|
||||
Arm::ExtReg Value::GetExtRegRef() const {
|
||||
DEBUG_ASSERT(type == Type::ExtRegRef);
|
||||
return inner.imm_extregref;
|
||||
}
|
||||
|
||||
Inst* Value::GetInst() const {
|
||||
DEBUG_ASSERT(type == Type::Opaque);
|
||||
return inner.inst;
|
||||
|
|
|
|||
|
|
@ -33,16 +33,17 @@ namespace IR {
|
|||
// A basic block is represented as an IR::Block.
|
||||
|
||||
enum class Type {
|
||||
Void = 1 << 0,
|
||||
RegRef = 1 << 1,
|
||||
Opaque = 1 << 2,
|
||||
U1 = 1 << 3,
|
||||
U8 = 1 << 4,
|
||||
U16 = 1 << 5,
|
||||
U32 = 1 << 6,
|
||||
U64 = 1 << 7,
|
||||
F32 = 1 << 8,
|
||||
F64 = 1 << 9,
|
||||
Void = 1 << 0,
|
||||
RegRef = 1 << 1,
|
||||
ExtRegRef = 1 << 2,
|
||||
Opaque = 1 << 3,
|
||||
U1 = 1 << 4,
|
||||
U8 = 1 << 5,
|
||||
U16 = 1 << 6,
|
||||
U32 = 1 << 7,
|
||||
U64 = 1 << 8,
|
||||
F32 = 1 << 9,
|
||||
F64 = 1 << 10,
|
||||
};
|
||||
|
||||
Type GetTypeOf(Opcode op);
|
||||
|
|
@ -72,6 +73,10 @@ public:
|
|||
inner.imm_regref = value;
|
||||
}
|
||||
|
||||
explicit Value(Arm::ExtReg value) : type(Type::ExtRegRef) {
|
||||
inner.imm_extregref = value;
|
||||
}
|
||||
|
||||
explicit Value(bool value) : type(Type::U1) {
|
||||
inner.imm_u1 = value;
|
||||
}
|
||||
|
|
@ -90,6 +95,7 @@ public:
|
|||
|
||||
Inst* GetInst() const;
|
||||
Arm::Reg GetRegRef() const;
|
||||
Arm::ExtReg GetExtRegRef() const;
|
||||
bool GetU1() const;
|
||||
u8 GetU8() const;
|
||||
u32 GetU32() const;
|
||||
|
|
@ -100,6 +106,7 @@ private:
|
|||
union {
|
||||
Inst* inst; // type == Type::Opaque
|
||||
Arm::Reg imm_regref;
|
||||
Arm::ExtReg imm_extregref;
|
||||
bool imm_u1;
|
||||
u8 imm_u8;
|
||||
u32 imm_u32;
|
||||
|
|
|
|||
|
|
@ -43,11 +43,31 @@ IR::Value IREmitter::GetRegister(Reg reg) {
|
|||
return Inst(IR::Opcode::GetRegister, { IR::Value(reg) });
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetExtendedRegister(ExtReg reg) {
|
||||
if (reg >= Arm::ExtReg::S0 && reg <= Arm::ExtReg::S31) {
|
||||
return Inst(IR::Opcode::GetExtendedRegister32, {IR::Value(reg)});
|
||||
} else if (reg >= Arm::ExtReg::D0 && reg <= Arm::ExtReg::D31) {
|
||||
return Inst(IR::Opcode::GetExtendedRegister64, {IR::Value(reg)});
|
||||
} else {
|
||||
ASSERT_MSG(false, "Invalid reg.");
|
||||
}
|
||||
}
|
||||
|
||||
void IREmitter::SetRegister(const Reg reg, const IR::Value& value) {
|
||||
ASSERT(reg != Reg::PC);
|
||||
Inst(IR::Opcode::SetRegister, { IR::Value(reg), value });
|
||||
}
|
||||
|
||||
void IREmitter::SetExtendedRegister(const ExtReg reg, const IR::Value& value) {
|
||||
if (reg >= Arm::ExtReg::S0 && reg <= Arm::ExtReg::S31) {
|
||||
Inst(IR::Opcode::SetExtendedRegister32, {IR::Value(reg), value});
|
||||
} else if (reg >= Arm::ExtReg::D0 && reg <= Arm::ExtReg::D31) {
|
||||
Inst(IR::Opcode::SetExtendedRegister64, {IR::Value(reg), value});
|
||||
} else {
|
||||
ASSERT_MSG(false, "Invalid reg.");
|
||||
}
|
||||
}
|
||||
|
||||
void IREmitter::ALUWritePC(const IR::Value& value) {
|
||||
// This behaviour is ARM version-dependent.
|
||||
// The below implementation is for ARMv6k
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ public:
|
|||
IR::Value Imm32(u32 value);
|
||||
|
||||
IR::Value GetRegister(Reg source_reg);
|
||||
IR::Value GetExtendedRegister(ExtReg source_reg);
|
||||
void SetRegister(const Reg dest_reg, const IR::Value& value);
|
||||
void SetExtendedRegister(const ExtReg dest_reg, const IR::Value& value);
|
||||
|
||||
void ALUWritePC(const IR::Value& value);
|
||||
void BranchWritePC(const IR::Value& value);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ OPCODE(Breakpoint, T::Void,
|
|||
|
||||
// ARM Context getters/setters
|
||||
OPCODE(GetRegister, T::U32, T::RegRef )
|
||||
OPCODE(GetExtendedRegister32, T::F32, T::ExtRegRef )
|
||||
OPCODE(GetExtendedRegister64, T::F64, T::ExtRegRef )
|
||||
OPCODE(SetRegister, T::Void, T::RegRef, T::U32 )
|
||||
OPCODE(SetExtendedRegister32, T::Void, T::ExtRegRef, T::F32 )
|
||||
OPCODE(SetExtendedRegister64, T::Void, T::ExtRegRef, T::F64 )
|
||||
OPCODE(GetNFlag, T::U1, )
|
||||
OPCODE(SetNFlag, T::Void, T::U1 )
|
||||
OPCODE(GetZFlag, T::U1, )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue