From e921c397ac59c2c6c2403325815cffb4c4cfe266 Mon Sep 17 00:00:00 2001 From: Merry Date: Sat, 30 Jul 2022 19:11:37 +0100 Subject: [PATCH] emit_arm64_data_processing: Fix BitImms for exceptional immediates --- .../backend/arm64/emit_arm64_data_processing.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp b/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp index ac2c5a2e..b3745b4b 100644 --- a/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64_data_processing.cpp @@ -964,13 +964,23 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& c [&](auto& Xresult, auto& Xa, auto& Xb) { code.SDIV(Xresult, Xa, Xb); }); } +template +static bool IsValidBitImm(u64 imm) { + static_assert(bitsize == 32 || bitsize == 64); + if constexpr (bitsize == 32) { + return static_cast(oaknut::detail::encode_bit_imm(static_cast(imm))); + } else { + return static_cast(oaknut::detail::encode_bit_imm(imm)); + } +} + template static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) { static_assert(bitsize == 32 || bitsize == 64); if constexpr (bitsize == 32) { imm = static_cast(imm); } - if (oaknut::detail::encode_bit_imm(imm)) { + if (IsValidBitImm(imm)) { emit_fn(imm); } else { code.MOV(Rscratch0(), imm); @@ -1039,7 +1049,7 @@ static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* const u64 not_imm = bitsize == 32 ? static_cast(~args[1].GetImmediateU64()) : ~args[1].GetImmediateU64(); - if (oaknut::detail::encode_bit_imm(not_imm)) { + if (IsValidBitImm(not_imm)) { code.ANDS(Rresult, Ra, not_imm); } else { code.MOV(Rscratch0(), args[1].GetImmediateU64()); @@ -1060,7 +1070,7 @@ static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* const u64 not_imm = bitsize == 32 ? static_cast(~args[1].GetImmediateU64()) : ~args[1].GetImmediateU64(); - if (oaknut::detail::encode_bit_imm(not_imm)) { + if (IsValidBitImm(not_imm)) { code.AND(Rresult, Ra, not_imm); } else { code.MOV(Rscratch0(), args[1].GetImmediateU64());