diff --git a/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp b/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp index c9a98aab..9f3a8508 100644 --- a/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp +++ b/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp @@ -145,18 +145,24 @@ void HandleNaNs(BlockOfCode& code, EmitContext& ctx, bool fpcr_controlled, std:: template Xbyak::Address GetVectorOf(BlockOfCode& code, u64 value) { - if constexpr (fsize == 32) { + if constexpr (fsize == 16) { + return code.MConst(xword, (value << 48) | (value << 32) | (value << 16) | value, (value << 48) | (value << 32) | (value << 16) | value); + } else if constexpr (fsize == 32) { return code.MConst(xword, (value << 32) | value, (value << 32) | value); } else { + static_assert(fsize == 64); return code.MConst(xword, value, value); } } template Xbyak::Address GetVectorOf(BlockOfCode& code) { - if constexpr (fsize == 32) { + if constexpr (fsize == 16) { + return code.MConst(xword, (value << 48) | (value << 32) | (value << 16) | value, (value << 48) | (value << 32) | (value << 16) | value); + } else if constexpr (fsize == 32) { return code.MConst(xword, (value << 32) | value, (value << 32) | value); } else { + static_assert(fsize == 64); return code.MConst(xword, value, value); } } @@ -173,6 +179,13 @@ Xbyak::Address GetNegativeZeroVector(BlockOfCode& code) { return GetVectorOf::Zero(true)>(code); } +template +Xbyak::Address GetNonSignMaskVector(BlockOfCode& code) { + using FPT = mcl::unsigned_integer_of_size; + constexpr FPT non_sign_mask = FP::FPInfo::exponent_mask | FP::FPInfo::mantissa_mask; + return GetVectorOf(code); +} + template Xbyak::Address GetSmallestNormalVector(BlockOfCode& code) { using FPT = mcl::unsigned_integer_of_size; @@ -586,17 +599,9 @@ void EmitFourOpFallback(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Lam template void FPVectorAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { - using FPT = mcl::unsigned_integer_of_size; - constexpr FPT non_sign_mask = FP::FPInfo::sign_mask - FPT(1u); - constexpr u64 non_sign_mask64 = mcl::bit::replicate_element(non_sign_mask); - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - const Xbyak::Xmm a = ctx.reg_alloc.UseScratchXmm(args[0]); - const Xbyak::Address mask = code.MConst(xword, non_sign_mask64, non_sign_mask64); - - code.andps(a, mask); - + code.andps(a, GetNonSignMaskVector(code)); ctx.reg_alloc.DefineValue(inst, a); }