diff --git a/src/backend_x64/emit_x64_vector.cpp b/src/backend_x64/emit_x64_vector.cpp index 6dd49336..2291f4bc 100644 --- a/src/backend_x64/emit_x64_vector.cpp +++ b/src/backend_x64/emit_x64_vector.cpp @@ -790,63 +790,43 @@ void EmitX64::EmitVectorLogicalShiftRight64(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } +template +static constexpr T LogicalVShift(T x, T y) { + const s8 shift_amount = static_cast(static_cast(y)); + const s64 bit_size = static_cast(Common::BitSize()); + + if (shift_amount <= -bit_size || shift_amount >= bit_size) { + return 0; + } + + if (shift_amount < 0) { + return x >> T(-shift_amount); + } + + return x << T(shift_amount); +} + void EmitX64::EmitVectorLogicalVShift8(EmitContext& ctx, IR::Inst* inst) { - EmitTwoArgumentFallback(code, ctx, inst, [](std::array& result, const std::array& a, const std::array& b){ - std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](u8 x, u8 y) -> u8 { - s8 shift_amount = static_cast(static_cast(y)); - if (shift_amount <= -8 || shift_amount >= 8) { - return 0; - } - if (shift_amount < 0) { - return x >> u8(-shift_amount); - } - return x << u8(shift_amount); - }); + EmitTwoArgumentFallback(code, ctx, inst, [](std::array& result, const std::array& a, const std::array& b) { + std::transform(a.begin(), a.end(), b.begin(), result.begin(), LogicalVShift); }); } void EmitX64::EmitVectorLogicalVShift16(EmitContext& ctx, IR::Inst* inst) { EmitTwoArgumentFallback(code, ctx, inst, [](std::array& result, const std::array& a, const std::array& b){ - std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](u16 x, u16 y) -> u16 { - s8 shift_amount = static_cast(static_cast(y)); - if (shift_amount <= -16 || shift_amount >= 16) { - return 0; - } - if (shift_amount < 0) { - return x >> u16(-shift_amount); - } - return x << u16(shift_amount); - }); + std::transform(a.begin(), a.end(), b.begin(), result.begin(), LogicalVShift); }); } void EmitX64::EmitVectorLogicalVShift32(EmitContext& ctx, IR::Inst* inst) { EmitTwoArgumentFallback(code, ctx, inst, [](std::array& result, const std::array& a, const std::array& b){ - std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](u32 x, u32 y) -> u32 { - s8 shift_amount = static_cast(static_cast(y)); - if (shift_amount <= -32 || shift_amount >= 32) { - return 0; - } - if (shift_amount < 0) { - return x >> u32(-shift_amount); - } - return x << u32(shift_amount); - }); + std::transform(a.begin(), a.end(), b.begin(), result.begin(), LogicalVShift); }); } void EmitX64::EmitVectorLogicalVShift64(EmitContext& ctx, IR::Inst* inst) { EmitTwoArgumentFallback(code, ctx, inst, [](std::array& result, const std::array& a, const std::array& b){ - std::transform(a.begin(), a.end(), b.begin(), result.begin(), [](u64 x, u64 y) -> u64 { - s8 shift_amount = static_cast(static_cast(y)); - if (shift_amount <= -64 || shift_amount >= 64) { - return 0; - } - if (shift_amount < 0) { - return x >> u64(-shift_amount); - } - return x << u64(shift_amount); - }); + std::transform(a.begin(), a.end(), b.begin(), result.begin(), LogicalVShift); }); }