From adb18fd0a70d899f4fd57b053d4960412c3ed31e Mon Sep 17 00:00:00 2001 From: Merry Date: Sat, 30 Jul 2022 12:44:02 +0100 Subject: [PATCH] emit_arm64_data_processing: Implement LogicalShift{Left,Right}64 --- .../arm64/emit_arm64_data_processing.cpp | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp b/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp index b03423f8..d8f2efa8 100644 --- a/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp @@ -321,10 +321,31 @@ void EmitIR(oaknut::CodeGenerator& code, EmitCon template<> void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { - (void)code; - (void)ctx; - (void)inst; - ASSERT_FALSE("Unimplemented"); + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + if (args[1].IsImmediate()) { + const u8 shift = args[1].GetImmediateU8(); + auto Xresult = ctx.reg_alloc.WriteX(inst); + auto Xoperand = ctx.reg_alloc.ReadX(args[0]); + RegAlloc::Realize(Xresult, Xoperand); + + if (shift <= 63) { + code.LSL(Xresult, Xoperand, shift); + } else { + code.MOV(Xresult, XZR); + } + } else { + auto Xresult = ctx.reg_alloc.WriteX(inst); + auto Xoperand = ctx.reg_alloc.ReadX(args[0]); + auto Xshift = ctx.reg_alloc.ReadX(args[1]); + RegAlloc::Realize(Xresult, Xoperand, Xshift); + ctx.reg_alloc.SpillFlags(); + + code.AND(Xscratch0, Xshift, 0xff); + code.LSL(Xresult, Xoperand, Xscratch0); + code.CMP(Xscratch0, 64); + code.CSEL(Xresult, Xresult, XZR, LT); + } } template<> @@ -430,10 +451,31 @@ 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"); + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + if (args[1].IsImmediate()) { + const u8 shift = args[1].GetImmediateU8(); + auto Xresult = ctx.reg_alloc.WriteX(inst); + auto Xoperand = ctx.reg_alloc.ReadX(args[0]); + RegAlloc::Realize(Xresult, Xoperand); + + if (shift <= 63) { + code.LSR(Xresult, Xoperand, shift); + } else { + code.MOV(Xresult, XZR); + } + } else { + auto Xresult = ctx.reg_alloc.WriteX(inst); + auto Xoperand = ctx.reg_alloc.ReadX(args[0]); + auto Xshift = ctx.reg_alloc.ReadX(args[1]); + RegAlloc::Realize(Xresult, Xoperand, Xshift); + ctx.reg_alloc.SpillFlags(); + + code.AND(Xscratch0, Xshift, 0xff); + code.LSR(Xresult, Xoperand, Xscratch0); + code.CMP(Xscratch0, 64); + code.CSEL(Xresult, Xresult, XZR, LT); + } } template<>