diff --git a/src/dynarmic/backend/arm64/emit_arm64.cpp b/src/dynarmic/backend/arm64/emit_arm64.cpp index fd3a324c..44b501b7 100644 --- a/src/dynarmic/backend/arm64/emit_arm64.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64.cpp @@ -30,6 +30,10 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst); template<> +void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst); +template<> +void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst); +template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst); template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst); diff --git a/src/dynarmic/backend/arm64/emit_arm64_a32.cpp b/src/dynarmic/backend/arm64/emit_arm64_a32.cpp index c98ca70b..84fc158c 100644 --- a/src/dynarmic/backend/arm64/emit_arm64_a32.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64_a32.cpp @@ -144,6 +144,34 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext code.LDR(Wresult, Xstate, offsetof(A32JitState, regs) + sizeof(u32) * static_cast(reg)); } +template<> +void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { + const A32::Reg reg = inst->GetArg(0).GetA32RegRef(); + ASSERT(A32::IsSingleExtReg(reg)); + const size_t index = static_cast(reg) - static_cast(A32::ExtReg::S0); + + auto Sresult = ctx.reg_alloc.WriteS(inst); + RegAlloc::Realize(Sresult); + + // TODO: Detect if Gpr vs Fpr is more appropriate + + code.LDR(Sresult, Xstate, offsetof(A32JitState, ext_regs) + sizeof(u32) * index); +} + +template<> +void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { + const A32::Reg reg = inst->GetArg(0).GetA32RegRef(); + ASSERT(A32::IsDoubleExtReg(reg)); + const size_t index = static_cast(reg) - static_cast(A32::ExtReg::D0); + + auto Dresult = ctx.reg_alloc.WriteD(inst); + RegAlloc::Realize(Dresult); + + // TODO: Detect if Gpr vs Fpr is more appropriate + + code.LDR(Dresult, Xstate, offsetof(A32JitState, ext_regs) + 2 * sizeof(u32) * index); +} + template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { const A32::Reg reg = inst->GetArg(0).GetA32RegRef();