emit_arm64_data_processing: Fix BitImms for exceptional immediates
This commit is contained in:
parent
f642f49b93
commit
e921c397ac
1 changed files with 13 additions and 3 deletions
|
@ -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());
|
||||||
|
|
Loading…
Reference in a new issue