emit_arm64_data_processing: Fix BitImms for exceptional immediates

This commit is contained in:
Merry 2022-07-30 19:11:37 +01:00 committed by merry
parent f642f49b93
commit e921c397ac

View file

@ -964,13 +964,23 @@ void EmitIR<IR::Opcode::SignedDiv64>(oaknut::CodeGenerator& code, EmitContext& c
[&](auto& Xresult, auto& Xa, auto& Xb) { code.SDIV(Xresult, Xa, Xb); }); [&](auto& Xresult, auto& Xa, auto& Xb) { code.SDIV(Xresult, Xa, Xb); });
} }
template<size_t bitsize>
static bool IsValidBitImm(u64 imm) {
static_assert(bitsize == 32 || bitsize == 64);
if constexpr (bitsize == 32) {
return static_cast<bool>(oaknut::detail::encode_bit_imm(static_cast<u32>(imm)));
} else {
return static_cast<bool>(oaknut::detail::encode_bit_imm(imm));
}
}
template<size_t bitsize, typename EmitFn> template<size_t bitsize, typename EmitFn>
static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) { static void MaybeBitImm(oaknut::CodeGenerator& code, u64 imm, EmitFn emit_fn) {
static_assert(bitsize == 32 || bitsize == 64); static_assert(bitsize == 32 || bitsize == 64);
if constexpr (bitsize == 32) { if constexpr (bitsize == 32) {
imm = static_cast<u32>(imm); imm = static_cast<u32>(imm);
} }
if (oaknut::detail::encode_bit_imm(imm)) { if (IsValidBitImm<bitsize>(imm)) {
emit_fn(imm); emit_fn(imm);
} else { } else {
code.MOV(Rscratch0<bitsize>(), imm); code.MOV(Rscratch0<bitsize>(), imm);
@ -1039,7 +1049,7 @@ static void EmitAndNot(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst*
const u64 not_imm = bitsize == 32 ? static_cast<u32>(~args[1].GetImmediateU64()) : ~args[1].GetImmediateU64(); const u64 not_imm = bitsize == 32 ? static_cast<u32>(~args[1].GetImmediateU64()) : ~args[1].GetImmediateU64();
if (oaknut::detail::encode_bit_imm(not_imm)) { if (IsValidBitImm<bitsize>(not_imm)) {
code.ANDS(Rresult, Ra, not_imm); code.ANDS(Rresult, Ra, not_imm);
} else { } else {
code.MOV(Rscratch0<bitsize>(), args[1].GetImmediateU64()); code.MOV(Rscratch0<bitsize>(), 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<u32>(~args[1].GetImmediateU64()) : ~args[1].GetImmediateU64(); const u64 not_imm = bitsize == 32 ? static_cast<u32>(~args[1].GetImmediateU64()) : ~args[1].GetImmediateU64();
if (oaknut::detail::encode_bit_imm(not_imm)) { if (IsValidBitImm<bitsize>(not_imm)) {
code.AND(Rresult, Ra, not_imm); code.AND(Rresult, Ra, not_imm);
} else { } else {
code.MOV(Rscratch0<bitsize>(), args[1].GetImmediateU64()); code.MOV(Rscratch0<bitsize>(), args[1].GetImmediateU64());