diff --git a/src/dynarmic/backend/arm64/emit_arm64_packed.cpp b/src/dynarmic/backend/arm64/emit_arm64_packed.cpp index 3f85d0dc..c5d16584 100644 --- a/src/dynarmic/backend/arm64/emit_arm64_packed.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64_packed.cpp @@ -197,7 +197,7 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& } } -template +template static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { const auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -222,7 +222,17 @@ static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR:: code.SUB(V1.S2(), V1.S2(), V2.S2()); code.SUB(Vresult->S2(), V0.S2(), V1.S2()); + if (is_halving) { + if (is_signed) { + code.SSHR(Vresult->S2(), Vresult->S2(), 1); + } else { + code.USHR(Vresult->S2(), Vresult->S2(), 1); + } + } + if (ge_inst) { + ASSERT(!is_halving); + auto Vge = ctx.reg_alloc.WriteD(ge_inst); RegAlloc::Realize(Vge); @@ -236,22 +246,22 @@ static void EmitPackedAddSub(oaknut::CodeGenerator& code, EmitContext& ctx, IR:: template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - EmitPackedAddSub(code, ctx, inst); + EmitPackedAddSub(code, ctx, inst); } template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - EmitPackedAddSub(code, ctx, inst); + EmitPackedAddSub(code, ctx, inst); } template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - EmitPackedAddSub(code, ctx, inst); + EmitPackedAddSub(code, ctx, inst); } template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - EmitPackedAddSub(code, ctx, inst); + EmitPackedAddSub(code, ctx, inst); } template<> @@ -320,34 +330,22 @@ void EmitIR(oaknut::CodeGenerator& code, EmitCo template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - ASSERT_FALSE("Unimplemented"); + EmitPackedAddSub(code, ctx, inst); } template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - ASSERT_FALSE("Unimplemented"); + EmitPackedAddSub(code, ctx, inst); } template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - ASSERT_FALSE("Unimplemented"); + EmitPackedAddSub(code, ctx, inst); } template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - ASSERT_FALSE("Unimplemented"); + EmitPackedAddSub(code, ctx, inst); } template<>