mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-05 22:41:18 +12:00
Add check for reg id and format in gpReg & fpReg
This commit is contained in:
parent
e3e1f8e62a
commit
d6c81fc720
1 changed files with 42 additions and 15 deletions
|
@ -281,16 +281,41 @@ struct AArch64GenContext_t : CodeGenerator
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<std::derived_from<VRegSc> T>
|
||||||
T fpReg(const IMLReg& imlReg)
|
T fpReg(const IMLReg& imlReg)
|
||||||
{
|
{
|
||||||
return T(imlReg.GetRegID() - IMLArchAArch64::PHYSREG_FPR_BASE);
|
cemu_assert_debug(imlReg.GetRegFormat() == IMLRegFormat::F64);
|
||||||
|
auto regId = imlReg.GetRegID();
|
||||||
|
cemu_assert_debug(regId >= IMLArchAArch64::PHYSREG_FPR_BASE && regId < IMLArchAArch64::PHYSREG_FPR_BASE + IMLArchAArch64::PHYSREG_FPR_COUNT);
|
||||||
|
return T(regId - IMLArchAArch64::PHYSREG_FPR_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<std::derived_from<RReg> T>
|
||||||
T gpReg(const IMLReg& imlReg)
|
T gpReg(const IMLReg& imlReg)
|
||||||
{
|
{
|
||||||
return T(imlReg.GetRegID() - IMLArchAArch64::PHYSREG_GPR_BASE);
|
auto regFormat = imlReg.GetRegFormat();
|
||||||
|
if (std::is_same_v<T, WReg>)
|
||||||
|
cemu_assert_debug(regFormat == IMLRegFormat::I32);
|
||||||
|
else if (std::is_same_v<T, XReg>)
|
||||||
|
cemu_assert_debug(regFormat == IMLRegFormat::I64);
|
||||||
|
else
|
||||||
|
cemu_assert_unimplemented();
|
||||||
|
|
||||||
|
auto regId = imlReg.GetRegID();
|
||||||
|
cemu_assert_debug(regId >= IMLArchAArch64::PHYSREG_GPR_BASE && regId < IMLArchAArch64::PHYSREG_GPR_BASE + IMLArchAArch64::PHYSREG_GPR_COUNT);
|
||||||
|
return T(regId - IMLArchAArch64::PHYSREG_GPR_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::derived_from<VRegSc> To, std::derived_from<VRegSc> From>
|
||||||
|
To aliasAs(const From& reg)
|
||||||
|
{
|
||||||
|
return To(reg.getIdx());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::derived_from<RReg> To, std::derived_from<RReg> From>
|
||||||
|
To aliasAs(const From& reg)
|
||||||
|
{
|
||||||
|
return To(reg.getIdx());
|
||||||
}
|
}
|
||||||
|
|
||||||
AArch64GenContext_t::AArch64GenContext_t(Allocator* allocator)
|
AArch64GenContext_t::AArch64GenContext_t(Allocator* allocator)
|
||||||
|
@ -356,7 +381,8 @@ void AArch64GenContext_t::r_name(IMLInstruction* imlInstruction)
|
||||||
|
|
||||||
if (imlInstruction->op_r_name.regR.GetBaseFormat() == IMLRegFormat::I64)
|
if (imlInstruction->op_r_name.regR.GetBaseFormat() == IMLRegFormat::I64)
|
||||||
{
|
{
|
||||||
WReg regR = gpReg<WReg>(imlInstruction->op_r_name.regR);
|
XReg regRXReg = gpReg<XReg>(imlInstruction->op_r_name.regR);
|
||||||
|
WReg regR = aliasAs<WReg>(regRXReg);
|
||||||
if (name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0 + 32)
|
if (name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0 + 32)
|
||||||
{
|
{
|
||||||
ldr(regR, AdrUimm(HCPU_REG, offsetof(PPCInterpreter_t, gpr) + sizeof(uint32) * (name - PPCREC_NAME_R0)));
|
ldr(regR, AdrUimm(HCPU_REG, offsetof(PPCInterpreter_t, gpr) + sizeof(uint32) * (name - PPCREC_NAME_R0)));
|
||||||
|
@ -436,7 +462,8 @@ void AArch64GenContext_t::name_r(IMLInstruction* imlInstruction)
|
||||||
|
|
||||||
if (imlInstruction->op_r_name.regR.GetBaseFormat() == IMLRegFormat::I64)
|
if (imlInstruction->op_r_name.regR.GetBaseFormat() == IMLRegFormat::I64)
|
||||||
{
|
{
|
||||||
auto regR = gpReg<WReg>(imlInstruction->op_r_name.regR);
|
XReg regRXReg = gpReg<XReg>(imlInstruction->op_r_name.regR);
|
||||||
|
WReg regR = aliasAs<WReg>(regRXReg);
|
||||||
if (name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0 + 32)
|
if (name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0 + 32)
|
||||||
{
|
{
|
||||||
str(regR, AdrUimm(HCPU_REG, offsetof(PPCInterpreter_t, gpr) + sizeof(uint32) * (name - PPCREC_NAME_R0)));
|
str(regR, AdrUimm(HCPU_REG, offsetof(PPCInterpreter_t, gpr) + sizeof(uint32) * (name - PPCREC_NAME_R0)));
|
||||||
|
@ -657,7 +684,7 @@ bool AArch64GenContext_t::r_r_s32_carry(IMLInstruction* imlInstruction)
|
||||||
bool AArch64GenContext_t::r_r_r(IMLInstruction* imlInstruction)
|
bool AArch64GenContext_t::r_r_r(IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
WReg regResult = gpReg<WReg>(imlInstruction->op_r_r_r.regR);
|
WReg regResult = gpReg<WReg>(imlInstruction->op_r_r_r.regR);
|
||||||
XReg reg64Result = gpReg<XReg>(imlInstruction->op_r_r_r.regR);
|
XReg reg64Result = aliasAs<XReg>(regResult);
|
||||||
WReg regOperand1 = gpReg<WReg>(imlInstruction->op_r_r_r.regA);
|
WReg regOperand1 = gpReg<WReg>(imlInstruction->op_r_r_r.regA);
|
||||||
WReg regOperand2 = gpReg<WReg>(imlInstruction->op_r_r_r.regB);
|
WReg regOperand2 = gpReg<WReg>(imlInstruction->op_r_r_r.regB);
|
||||||
|
|
||||||
|
@ -859,12 +886,12 @@ bool AArch64GenContext_t::macro(IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
if (imlInstruction->operation == PPCREC_IML_MACRO_B_TO_REG)
|
if (imlInstruction->operation == PPCREC_IML_MACRO_B_TO_REG)
|
||||||
{
|
{
|
||||||
XReg branchDstReg = gpReg<XReg>(imlInstruction->op_macro.paramReg);
|
WReg branchDstReg = gpReg<WReg>(imlInstruction->op_macro.paramReg);
|
||||||
|
|
||||||
mov(TEMP_GPR1.XReg, offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable));
|
mov(TEMP_GPR1.WReg, offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable));
|
||||||
add(TEMP_GPR1.XReg, TEMP_GPR1.XReg, branchDstReg, ShMod::LSL, 1);
|
add(TEMP_GPR1.WReg, TEMP_GPR1.WReg, branchDstReg, ShMod::LSL, 1);
|
||||||
ldr(TEMP_GPR1.XReg, AdrReg(PPC_REC_INSTANCE_REG, TEMP_GPR1.XReg));
|
ldr(TEMP_GPR1.XReg, AdrExt(PPC_REC_INSTANCE_REG, TEMP_GPR1.WReg, ExtMod::UXTW));
|
||||||
mov(LR.XReg, branchDstReg);
|
mov(LR.WReg, branchDstReg);
|
||||||
br(TEMP_GPR1.XReg);
|
br(TEMP_GPR1.XReg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1390,9 +1417,9 @@ Cond ImlFPCondToArm64Cond(IMLCondition cond)
|
||||||
|
|
||||||
void AArch64GenContext_t::fpr_compare(IMLInstruction* imlInstruction)
|
void AArch64GenContext_t::fpr_compare(IMLInstruction* imlInstruction)
|
||||||
{
|
{
|
||||||
auto regR = gpReg<XReg>(imlInstruction->op_fpr_compare.regR);
|
WReg regR = gpReg<WReg>(imlInstruction->op_fpr_compare.regR);
|
||||||
auto regA = fpReg<DReg>(imlInstruction->op_fpr_compare.regA);
|
DReg regA = fpReg<DReg>(imlInstruction->op_fpr_compare.regA);
|
||||||
auto regB = fpReg<DReg>(imlInstruction->op_fpr_compare.regB);
|
DReg regB = fpReg<DReg>(imlInstruction->op_fpr_compare.regB);
|
||||||
auto cond = ImlFPCondToArm64Cond(imlInstruction->op_fpr_compare.cond);
|
auto cond = ImlFPCondToArm64Cond(imlInstruction->op_fpr_compare.cond);
|
||||||
fcmp(regA, regB);
|
fcmp(regA, regB);
|
||||||
cset(regR, cond);
|
cset(regR, cond);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue