emit_x64_vector_floating_point: Introduce ICODE

This commit is contained in:
MerryMage 2020-06-25 19:28:49 +01:00
parent 4f967387c0
commit 7022281a0b

View file

@ -35,18 +35,22 @@ using namespace Xbyak::util;
namespace { namespace {
template<size_t fsize, typename T> #define FCODE(NAME) \
T ChooseOnFsize([[maybe_unused]] T f32, [[maybe_unused]] T f64) { [&code](auto... args){ \
static_assert(fsize == 32 || fsize == 64, "fsize must be either 32 or 64"); if constexpr (fsize == 32) { \
code.NAME##s(args...); \
if constexpr (fsize == 32) { } else { \
return f32; code.NAME##d(args...); \
} else { } \
return f64; }
#define ICODE(NAME) \
[&code](auto... args){ \
if constexpr (fsize == 32) { \
code.NAME##d(args...); \
} else { \
code.NAME##q(args...); \
} \
} }
}
#define FCODE(NAME) (code.*ChooseOnFsize<fsize>(&Xbyak::CodeGenerator::NAME##s, &Xbyak::CodeGenerator::NAME##d))
template<typename Lambda> template<typename Lambda>
void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_controlled, Lambda lambda) { void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_controlled, Lambda lambda) {
@ -1370,11 +1374,7 @@ static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
// An explanation for this is given in EmitFPRSqrtStepFused. // An explanation for this is given in EmitFPRSqrtStepFused.
code.vmovaps(mask, GetVectorOf<fsize, fsize == 32 ? 0x7f000000 : 0x7fe0000000000000>(code)); code.vmovaps(mask, GetVectorOf<fsize, fsize == 32 ? 0x7f000000 : 0x7fe0000000000000>(code));
FCODE(vandp)(tmp, result, mask); FCODE(vandp)(tmp, result, mask);
if constexpr (fsize == 32) { ICODE(vpcmpeq)(tmp, tmp, mask);
code.vpcmpeqd(tmp, tmp, mask);
} else {
code.vpcmpeqq(tmp, tmp, mask);
}
code.ptest(tmp, tmp); code.ptest(tmp, tmp);
code.jnz(fallback, code.T_NEAR); code.jnz(fallback, code.T_NEAR);
@ -1517,11 +1517,7 @@ void EmitFPVectorToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
FCODE(andp)(tmp, xmm0); FCODE(andp)(tmp, xmm0);
FCODE(subp)(src, tmp); FCODE(subp)(src, tmp);
perform_conversion(src); perform_conversion(src);
if constexpr (fsize == 32) { ICODE(psll)(xmm0, static_cast<u8>(fsize - 1));
code.pslld(xmm0, 31);
} else {
code.psllq(xmm0, 63);
}
FCODE(orp)(src, xmm0); FCODE(orp)(src, xmm0);
// Saturate to max // Saturate to max