A32/IR: Add SetVector and GetVector
This commit is contained in:
parent
e85a08ec34
commit
07108246cf
9 changed files with 141 additions and 27 deletions
|
@ -51,6 +51,10 @@ static Xbyak::Address MJitStateExtReg(A32::ExtReg reg) {
|
||||||
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
|
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::D0);
|
||||||
return qword[r15 + offsetof(A32JitState, ExtReg) + sizeof(u64) * index];
|
return qword[r15 + offsetof(A32JitState, ExtReg) + sizeof(u64) * index];
|
||||||
}
|
}
|
||||||
|
if (A32::IsQuadExtReg(reg)) {
|
||||||
|
const size_t index = static_cast<size_t>(reg) - static_cast<size_t>(A32::ExtReg::Q0);
|
||||||
|
return xword[r15 + offsetof(A32JitState, ExtReg) + 2 * sizeof(u64) * index];
|
||||||
|
}
|
||||||
ASSERT_FALSE("Should never happen.");
|
ASSERT_FALSE("Should never happen.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +343,19 @@ void A32EmitX64::EmitA32GetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
|
||||||
ctx.reg_alloc.DefineValue(inst, result);
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void A32EmitX64::EmitA32GetVector(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||||
|
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||||
|
|
||||||
|
const Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm();
|
||||||
|
if (A32::IsDoubleExtReg(reg)) {
|
||||||
|
code.movsd(result, MJitStateExtReg(reg));
|
||||||
|
} else {
|
||||||
|
code.movaps(result, MJitStateExtReg(reg));
|
||||||
|
}
|
||||||
|
ctx.reg_alloc.DefineValue(inst, result);
|
||||||
|
}
|
||||||
|
|
||||||
void A32EmitX64::EmitA32SetRegister(A32EmitContext& ctx, IR::Inst* inst) {
|
void A32EmitX64::EmitA32SetRegister(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
const A32::Reg reg = inst->GetArg(0).GetA32RegRef();
|
const A32::Reg reg = inst->GetArg(0).GetA32RegRef();
|
||||||
|
@ -382,6 +399,19 @@ void A32EmitX64::EmitA32SetExtendedRegister64(A32EmitContext& ctx, IR::Inst* ins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void A32EmitX64::EmitA32SetVector(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||||
|
ASSERT(A32::IsDoubleExtReg(reg) || A32::IsQuadExtReg(reg));
|
||||||
|
|
||||||
|
const Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
|
||||||
|
if (A32::IsDoubleExtReg(reg)) {
|
||||||
|
code.movsd(MJitStateExtReg(reg), to_store);
|
||||||
|
} else {
|
||||||
|
code.movaps(MJitStateExtReg(reg), to_store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static u32 GetCpsrImpl(A32JitState* jit_state) {
|
static u32 GetCpsrImpl(A32JitState* jit_state) {
|
||||||
return jit_state->Cpsr();
|
return jit_state->Cpsr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ struct A32JitState {
|
||||||
u32 Cpsr() const;
|
u32 Cpsr() const;
|
||||||
void SetCpsr(u32 cpsr);
|
void SetCpsr(u32 cpsr);
|
||||||
|
|
||||||
alignas(u64) std::array<u32, 64> ExtReg{}; // Extension registers.
|
alignas(16) std::array<u32, 64> ExtReg{}; // Extension registers.
|
||||||
|
|
||||||
static constexpr size_t SpillCount = 64;
|
static constexpr size_t SpillCount = 64;
|
||||||
std::array<u64, SpillCount> Spill{}; // Spill.
|
alignas(16) std::array<std::array<u64, 2>, SpillCount> spill{}; // Spill.
|
||||||
static Xbyak::Address GetSpillLocationFromIndex(size_t i) {
|
static Xbyak::Address GetSpillLocationFromIndex(size_t i) {
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
return qword[r15 + offsetof(A32JitState, Spill) + i * sizeof(u64)];
|
return xword[r15 + offsetof(A32JitState, spill) + i * sizeof(u64) * 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// For internal use (See: BlockOfCode::RunCode)
|
// For internal use (See: BlockOfCode::RunCode)
|
||||||
|
|
|
@ -41,6 +41,11 @@ IR::U32U64 IREmitter::GetExtendedRegister(ExtReg reg) {
|
||||||
ASSERT_FALSE("Invalid 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) {
|
void IREmitter::SetRegister(const Reg reg, const IR::U32& value) {
|
||||||
ASSERT(reg != A32::Reg::PC);
|
ASSERT(reg != A32::Reg::PC);
|
||||||
Inst(Opcode::A32SetRegister, IR::Value(reg), value);
|
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) {
|
void IREmitter::ALUWritePC(const IR::U32& value) {
|
||||||
// This behaviour is ARM version-dependent.
|
// This behaviour is ARM version-dependent.
|
||||||
// The below implementation is for ARMv6k
|
// The below implementation is for ARMv6k
|
||||||
|
|
|
@ -33,8 +33,10 @@ public:
|
||||||
|
|
||||||
IR::U32 GetRegister(Reg source_reg);
|
IR::U32 GetRegister(Reg source_reg);
|
||||||
IR::U32U64 GetExtendedRegister(ExtReg source_reg);
|
IR::U32U64 GetExtendedRegister(ExtReg source_reg);
|
||||||
|
IR::U128 GetVector(ExtReg source_reg);
|
||||||
void SetRegister(Reg dest_reg, const IR::U32& value);
|
void SetRegister(Reg dest_reg, const IR::U32& value);
|
||||||
void SetExtendedRegister(ExtReg dest_reg, const IR::U32U64& 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 ALUWritePC(const IR::U32& value);
|
||||||
void BranchWritePC(const IR::U32& value);
|
void BranchWritePC(const IR::U32& value);
|
||||||
|
|
|
@ -38,6 +38,9 @@ const char* ExtRegToString(ExtReg reg) {
|
||||||
"d9", "d10", "d11", "d12", "d13", "d14", "d15", "d16",
|
"d9", "d10", "d11", "d12", "d13", "d14", "d15", "d16",
|
||||||
"d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
|
"d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24",
|
||||||
"d25", "d26", "d27", "d28", "d29", "d30", "d31",
|
"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));
|
return reg_strs.at(static_cast<size_t>(reg));
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ enum class ExtReg {
|
||||||
D8, D9, D10, D11, D12, D13, D14, D15,
|
D8, D9, D10, D11, D12, D13, D14, D15,
|
||||||
D16, D17, D18, D19, D20, D21, D22, D23,
|
D16, D17, D18, D19, D20, D21, D22, D23,
|
||||||
D24, D25, D26, D27, D28, D29, D30, D31,
|
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;
|
using RegList = u16;
|
||||||
|
@ -73,6 +75,10 @@ constexpr bool IsDoubleExtReg(ExtReg reg) {
|
||||||
return reg >= ExtReg::D0 && reg <= ExtReg::D31;
|
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) {
|
inline size_t RegNumber(Reg reg) {
|
||||||
ASSERT(reg != Reg::INVALID_REG);
|
ASSERT(reg != Reg::INVALID_REG);
|
||||||
return static_cast<size_t>(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);
|
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");
|
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);
|
const auto new_reg = static_cast<ExtReg>(static_cast<size_t>(reg) + number);
|
||||||
|
|
||||||
ASSERT((IsSingleExtReg(reg) && IsSingleExtReg(new_reg)) ||
|
ASSERT((IsSingleExtReg(reg) && IsSingleExtReg(new_reg)) ||
|
||||||
(IsDoubleExtReg(reg) && IsDoubleExtReg(new_reg)));
|
(IsDoubleExtReg(reg) && IsDoubleExtReg(new_reg)) ||
|
||||||
|
(IsQuadExtReg(reg) && IsQuadExtReg(new_reg)));
|
||||||
|
|
||||||
return 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) {
|
inline ExtReg ToExtRegD(size_t base, bool bit) {
|
||||||
return ExtReg::D0 + (base + (bit ? 16 : 0));
|
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) {
|
inline ExtReg ToExtReg(bool sz, size_t base, bool bit) {
|
||||||
if (sz) {
|
return sz ? ToExtRegD(base, bit) : ToExtRegS(base, bit);
|
||||||
return ToExtRegD(base, bit);
|
}
|
||||||
} else {
|
|
||||||
return ToExtRegS(base, bit);
|
inline ExtReg ToVector(bool Q, size_t base, bool bit) {
|
||||||
}
|
return Q ? ToExtRegQ(base, bit) : ToExtRegD(base, bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A32
|
} // namespace Dynarmic::A32
|
||||||
|
|
|
@ -198,6 +198,7 @@ bool Inst::ReadsFromCoreRegister() const {
|
||||||
case Opcode::A32GetRegister:
|
case Opcode::A32GetRegister:
|
||||||
case Opcode::A32GetExtendedRegister32:
|
case Opcode::A32GetExtendedRegister32:
|
||||||
case Opcode::A32GetExtendedRegister64:
|
case Opcode::A32GetExtendedRegister64:
|
||||||
|
case Opcode::A32GetVector:
|
||||||
case Opcode::A64GetW:
|
case Opcode::A64GetW:
|
||||||
case Opcode::A64GetX:
|
case Opcode::A64GetX:
|
||||||
case Opcode::A64GetS:
|
case Opcode::A64GetS:
|
||||||
|
@ -216,6 +217,7 @@ bool Inst::WritesToCoreRegister() const {
|
||||||
case Opcode::A32SetRegister:
|
case Opcode::A32SetRegister:
|
||||||
case Opcode::A32SetExtendedRegister32:
|
case Opcode::A32SetExtendedRegister32:
|
||||||
case Opcode::A32SetExtendedRegister64:
|
case Opcode::A32SetExtendedRegister64:
|
||||||
|
case Opcode::A32SetVector:
|
||||||
case Opcode::A32BXWritePC:
|
case Opcode::A32BXWritePC:
|
||||||
case Opcode::A64SetW:
|
case Opcode::A64SetW:
|
||||||
case Opcode::A64SetX:
|
case Opcode::A64SetX:
|
||||||
|
|
|
@ -9,9 +9,11 @@ A32OPC(SetCheckBit, Void, U1
|
||||||
A32OPC(GetRegister, U32, A32Reg )
|
A32OPC(GetRegister, U32, A32Reg )
|
||||||
A32OPC(GetExtendedRegister32, U32, A32ExtReg )
|
A32OPC(GetExtendedRegister32, U32, A32ExtReg )
|
||||||
A32OPC(GetExtendedRegister64, U64, A32ExtReg )
|
A32OPC(GetExtendedRegister64, U64, A32ExtReg )
|
||||||
|
A32OPC(GetVector, U128, A32ExtReg )
|
||||||
A32OPC(SetRegister, Void, A32Reg, U32 )
|
A32OPC(SetRegister, Void, A32Reg, U32 )
|
||||||
A32OPC(SetExtendedRegister32, Void, A32ExtReg, U32 )
|
A32OPC(SetExtendedRegister32, Void, A32ExtReg, U32 )
|
||||||
A32OPC(SetExtendedRegister64, Void, A32ExtReg, U64 )
|
A32OPC(SetExtendedRegister64, Void, A32ExtReg, U64 )
|
||||||
|
A32OPC(SetVector, Void, A32ExtReg, U128 )
|
||||||
A32OPC(GetCpsr, U32, )
|
A32OPC(GetCpsr, U32, )
|
||||||
A32OPC(SetCpsr, Void, U32 )
|
A32OPC(SetCpsr, Void, U32 )
|
||||||
A32OPC(SetCpsrNZCV, Void, U32 )
|
A32OPC(SetCpsrNZCV, Void, U32 )
|
||||||
|
|
|
@ -23,8 +23,10 @@ void A32GetSetElimination(IR::Block& block) {
|
||||||
Iterator last_set_instruction;
|
Iterator last_set_instruction;
|
||||||
};
|
};
|
||||||
std::array<RegisterInfo, 15> reg_info;
|
std::array<RegisterInfo, 15> reg_info;
|
||||||
std::array<RegisterInfo, 32> ext_reg_singles_info;
|
std::array<RegisterInfo, 64> ext_reg_singles_info;
|
||||||
std::array<RegisterInfo, 32> ext_reg_doubles_info;
|
std::array<RegisterInfo, 32> ext_reg_doubles_info;
|
||||||
|
std::array<RegisterInfo, 32> ext_reg_vector_double_info;
|
||||||
|
std::array<RegisterInfo, 16> ext_reg_vector_quad_info;
|
||||||
struct CpsrInfo {
|
struct CpsrInfo {
|
||||||
RegisterInfo n;
|
RegisterInfo n;
|
||||||
RegisterInfo z;
|
RegisterInfo z;
|
||||||
|
@ -75,10 +77,9 @@ void A32GetSetElimination(IR::Block& block) {
|
||||||
const size_t reg_index = A32::RegNumber(reg);
|
const size_t reg_index = A32::RegNumber(reg);
|
||||||
do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst);
|
do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst);
|
||||||
|
|
||||||
const size_t doubles_reg_index = reg_index / 2;
|
ext_reg_doubles_info[reg_index / 2] = {};
|
||||||
if (doubles_reg_index < ext_reg_doubles_info.size()) {
|
ext_reg_vector_double_info[reg_index / 2] = {};
|
||||||
ext_reg_doubles_info[doubles_reg_index] = {};
|
ext_reg_vector_quad_info[reg_index / 4] = {};
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IR::Opcode::A32GetExtendedRegister32: {
|
case IR::Opcode::A32GetExtendedRegister32: {
|
||||||
|
@ -86,10 +87,9 @@ void A32GetSetElimination(IR::Block& block) {
|
||||||
const size_t reg_index = A32::RegNumber(reg);
|
const size_t reg_index = A32::RegNumber(reg);
|
||||||
do_get(ext_reg_singles_info[reg_index], inst);
|
do_get(ext_reg_singles_info[reg_index], inst);
|
||||||
|
|
||||||
const size_t doubles_reg_index = reg_index / 2;
|
ext_reg_doubles_info[reg_index / 2] = {};
|
||||||
if (doubles_reg_index < ext_reg_doubles_info.size()) {
|
ext_reg_vector_double_info[reg_index / 2] = {};
|
||||||
ext_reg_doubles_info[doubles_reg_index] = {};
|
ext_reg_vector_quad_info[reg_index / 4] = {};
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IR::Opcode::A32SetExtendedRegister64: {
|
case IR::Opcode::A32SetExtendedRegister64: {
|
||||||
|
@ -97,11 +97,10 @@ void A32GetSetElimination(IR::Block& block) {
|
||||||
const size_t reg_index = A32::RegNumber(reg);
|
const size_t reg_index = A32::RegNumber(reg);
|
||||||
do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst);
|
do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst);
|
||||||
|
|
||||||
const size_t singles_reg_index = reg_index * 2;
|
ext_reg_singles_info[reg_index * 2 + 0] = {};
|
||||||
if (singles_reg_index < ext_reg_singles_info.size()) {
|
ext_reg_singles_info[reg_index * 2 + 1] = {};
|
||||||
ext_reg_singles_info[singles_reg_index] = {};
|
ext_reg_vector_double_info[reg_index] = {};
|
||||||
ext_reg_singles_info[singles_reg_index+1] = {};
|
ext_reg_vector_quad_info[reg_index / 2] = {};
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IR::Opcode::A32GetExtendedRegister64: {
|
case IR::Opcode::A32GetExtendedRegister64: {
|
||||||
|
@ -109,10 +108,61 @@ void A32GetSetElimination(IR::Block& block) {
|
||||||
const size_t reg_index = A32::RegNumber(reg);
|
const size_t reg_index = A32::RegNumber(reg);
|
||||||
do_get(ext_reg_doubles_info[reg_index], inst);
|
do_get(ext_reg_doubles_info[reg_index], inst);
|
||||||
|
|
||||||
const size_t singles_reg_index = reg_index * 2;
|
ext_reg_singles_info[reg_index * 2 + 0] = {};
|
||||||
if (singles_reg_index < ext_reg_singles_info.size()) {
|
ext_reg_singles_info[reg_index * 2 + 1] = {};
|
||||||
ext_reg_singles_info[singles_reg_index] = {};
|
ext_reg_vector_double_info[reg_index] = {};
|
||||||
ext_reg_singles_info[singles_reg_index+1] = {};
|
ext_reg_vector_quad_info[reg_index / 2] = {};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR::Opcode::A32SetVector: {
|
||||||
|
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||||
|
const size_t reg_index = A32::RegNumber(reg);
|
||||||
|
if (A32::IsDoubleExtReg(reg)) {
|
||||||
|
do_set(ext_reg_vector_double_info[reg_index], inst->GetArg(1), inst);
|
||||||
|
|
||||||
|
ext_reg_singles_info[reg_index * 2 + 0] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 2 + 1] = {};
|
||||||
|
ext_reg_doubles_info[reg_index] = {};
|
||||||
|
ext_reg_vector_quad_info[reg_index / 2] = {};
|
||||||
|
} else {
|
||||||
|
DEBUG_ASSERT(A32::IsQuadExtReg(reg));
|
||||||
|
|
||||||
|
do_set(ext_reg_vector_quad_info[reg_index], inst->GetArg(1), inst);
|
||||||
|
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 0] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 1] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 2] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 3] = {};
|
||||||
|
ext_reg_doubles_info[reg_index * 2 + 0] = {};
|
||||||
|
ext_reg_doubles_info[reg_index * 2 + 1] = {};
|
||||||
|
ext_reg_vector_double_info[reg_index * 2 + 0] = {};
|
||||||
|
ext_reg_vector_double_info[reg_index * 2 + 1] = {};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR::Opcode::A32GetVector: {
|
||||||
|
const A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef();
|
||||||
|
const size_t reg_index = A32::RegNumber(reg);
|
||||||
|
if (A32::IsDoubleExtReg(reg)) {
|
||||||
|
do_get(ext_reg_vector_double_info[reg_index], inst);
|
||||||
|
|
||||||
|
ext_reg_singles_info[reg_index * 2 + 0] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 2 + 1] = {};
|
||||||
|
ext_reg_doubles_info[reg_index] = {};
|
||||||
|
ext_reg_vector_quad_info[reg_index / 2] = {};
|
||||||
|
} else {
|
||||||
|
DEBUG_ASSERT(A32::IsQuadExtReg(reg));
|
||||||
|
|
||||||
|
do_get(ext_reg_vector_quad_info[reg_index], inst);
|
||||||
|
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 0] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 1] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 2] = {};
|
||||||
|
ext_reg_singles_info[reg_index * 4 + 3] = {};
|
||||||
|
ext_reg_doubles_info[reg_index * 2 + 0] = {};
|
||||||
|
ext_reg_doubles_info[reg_index * 2 + 1] = {};
|
||||||
|
ext_reg_vector_double_info[reg_index * 2 + 0] = {};
|
||||||
|
ext_reg_vector_double_info[reg_index * 2 + 1] = {};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue