luau/CodeGen/src/EmitBuiltinsX64.cpp

365 lines
14 KiB
C++
Raw Normal View History

2022-10-14 01:59:53 +03:00
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
#include "EmitBuiltinsX64.h"
#include "Luau/AssemblyBuilderX64.h"
#include "Luau/Bytecode.h"
#include "EmitCommonX64.h"
2023-03-03 15:45:38 +02:00
#include "IrRegAllocX64.h"
2023-01-03 19:33:19 +02:00
#include "NativeState.h"
2022-10-14 01:59:53 +03:00
#include "lstate.h"
2023-02-24 10:24:22 -08:00
// TODO: LBF_MATH_FREXP and LBF_MATH_MODF can work for 1 result case if second store is removed
2022-10-14 01:59:53 +03:00
namespace Luau
{
namespace CodeGen
{
2023-03-03 15:45:38 +02:00
namespace X64
2022-10-14 01:59:53 +03:00
{
2023-03-03 15:45:38 +02:00
void emitBuiltinMathFloor(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
{
ScopedRegX64 tmp{regs, SizeX64::xmmword};
build.vroundsd(tmp.reg, tmp.reg, luauRegValue(arg), RoundingModeX64::RoundToNegativeInfinity);
build.vmovsd(luauRegValue(ra), tmp.reg);
2022-10-14 01:59:53 +03:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathCeil(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2022-10-14 01:59:53 +03:00
{
2023-03-03 15:45:38 +02:00
ScopedRegX64 tmp{regs, SizeX64::xmmword};
build.vroundsd(tmp.reg, tmp.reg, luauRegValue(arg), RoundingModeX64::RoundToPositiveInfinity);
build.vmovsd(luauRegValue(ra), tmp.reg);
2022-10-14 01:59:53 +03:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathSqrt(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2022-10-14 01:59:53 +03:00
{
2023-03-03 15:45:38 +02:00
ScopedRegX64 tmp{regs, SizeX64::xmmword};
build.vsqrtsd(tmp.reg, tmp.reg, luauRegValue(arg));
build.vmovsd(luauRegValue(ra), tmp.reg);
2022-10-14 01:59:53 +03:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathAbs(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
ScopedRegX64 tmp{regs, SizeX64::xmmword};
build.vmovsd(tmp.reg, luauRegValue(arg));
build.vandpd(tmp.reg, tmp.reg, build.i64(~(1LL << 63)));
build.vmovsd(luauRegValue(ra), tmp.reg);
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
static void emitBuiltinMathSingleArgFunc(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg, int32_t offset)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-01-03 19:33:19 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
build.call(qword[rNativeContext + offset]);
build.vmovsd(luauRegValue(ra), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathExp(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_exp));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathFmod(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-01-03 19:33:19 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
build.vmovsd(xmm1, qword[args + offsetof(TValue, value)]);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_fmod)]);
build.vmovsd(luauRegValue(ra), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathPow(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-01-03 19:33:19 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
build.vmovsd(xmm1, qword[args + offsetof(TValue, value)]);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_pow)]);
build.vmovsd(luauRegValue(ra), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathAsin(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_asin));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathSin(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_sin));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathSinh(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_sinh));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathAcos(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_acos));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathCos(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_cos));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathCosh(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_cosh));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathAtan(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_atan));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathTan(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_tan));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathTanh(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_tanh));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathAtan2(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-01-03 19:33:19 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
build.vmovsd(xmm1, qword[args + offsetof(TValue, value)]);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_atan2)]);
build.vmovsd(luauRegValue(ra), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathLog10(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
emitBuiltinMathSingleArgFunc(regs, build, ra, arg, offsetof(NativeContext, libm_log10));
2023-01-03 19:33:19 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathLog(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-01-03 19:33:19 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-01-03 19:33:19 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
if (nparams == 1)
{
build.call(qword[rNativeContext + offsetof(NativeContext, libm_log)]);
}
else
{
Label log10check, logdivlog, exit;
// Using 'rbx' for non-volatile temporary storage of log(arg1) result
RegisterX64 tmp = rbx;
OperandX64 arg2value = qword[args + offsetof(TValue, value)];
build.vmovsd(xmm1, arg2value);
2023-03-03 15:45:38 +02:00
jumpOnNumberCmp(build, noreg, build.f64(2.0), xmm1, IrCondition::NotEqual, log10check);
2023-01-03 19:33:19 +02:00
build.call(qword[rNativeContext + offsetof(NativeContext, libm_log2)]);
build.jmp(exit);
build.setLabel(log10check);
2023-03-03 15:45:38 +02:00
jumpOnNumberCmp(build, noreg, build.f64(10.0), xmm1, IrCondition::NotEqual, logdivlog);
2023-01-03 19:33:19 +02:00
build.call(qword[rNativeContext + offsetof(NativeContext, libm_log10)]);
build.jmp(exit);
build.setLabel(logdivlog);
// log(arg1)
build.call(qword[rNativeContext + offsetof(NativeContext, libm_log)]);
build.vmovq(tmp, xmm0);
// log(arg2)
build.vmovsd(xmm0, arg2value);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_log)]);
// log(arg1) / log(arg2)
build.vmovq(xmm1, tmp);
build.vdivsd(xmm0, xmm1, xmm0);
build.setLabel(exit);
}
build.vmovsd(luauRegValue(ra), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathLdexp(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-02-03 14:34:12 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
if (build.abi == ABIX64::Windows)
build.vcvttsd2si(rArg2, qword[args + offsetof(TValue, value)]);
else
build.vcvttsd2si(rArg1, qword[args + offsetof(TValue, value)]);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_ldexp)]);
build.vmovsd(luauRegValue(ra), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathRound(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-03 15:45:38 +02:00
ScopedRegX64 tmp0{regs, SizeX64::xmmword};
ScopedRegX64 tmp1{regs, SizeX64::xmmword};
ScopedRegX64 tmp2{regs, SizeX64::xmmword};
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
build.vmovsd(tmp0.reg, luauRegValue(arg));
build.vandpd(tmp1.reg, tmp0.reg, build.f64x2(-0.0, -0.0));
build.vmovsd(tmp2.reg, build.i64(0x3fdfffffffffffff)); // 0.49999999999999994
build.vorpd(tmp1.reg, tmp1.reg, tmp2.reg);
build.vaddsd(tmp0.reg, tmp0.reg, tmp1.reg);
build.vroundsd(tmp0.reg, tmp0.reg, tmp0.reg, RoundingModeX64::RoundToZero);
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
build.vmovsd(luauRegValue(ra), tmp0.reg);
2023-02-03 14:34:12 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathFrexp(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-02-03 14:34:12 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
if (build.abi == ABIX64::Windows)
build.lea(rArg2, sTemporarySlot);
else
build.lea(rArg1, sTemporarySlot);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_frexp)]);
build.vmovsd(luauRegValue(ra), xmm0);
build.vcvtsi2sd(xmm0, xmm0, dword[sTemporarySlot + 0]);
build.vmovsd(luauRegValue(ra + 1), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathModf(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-03 15:45:38 +02:00
regs.assertAllFree();
2023-02-03 14:34:12 +02:00
build.vmovsd(xmm0, luauRegValue(arg));
if (build.abi == ABIX64::Windows)
build.lea(rArg2, sTemporarySlot);
else
build.lea(rArg1, sTemporarySlot);
build.call(qword[rNativeContext + offsetof(NativeContext, libm_modf)]);
build.vmovsd(xmm1, qword[sTemporarySlot + 0]);
build.vmovsd(luauRegValue(ra), xmm1);
build.vmovsd(luauRegValue(ra + 1), xmm0);
}
2023-03-03 15:45:38 +02:00
void emitBuiltinMathSign(IrRegAllocX64& regs, AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-03 15:45:38 +02:00
ScopedRegX64 tmp0{regs, SizeX64::xmmword};
ScopedRegX64 tmp1{regs, SizeX64::xmmword};
ScopedRegX64 tmp2{regs, SizeX64::xmmword};
ScopedRegX64 tmp3{regs, SizeX64::xmmword};
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
build.vmovsd(tmp0.reg, luauRegValue(arg));
build.vxorpd(tmp1.reg, tmp1.reg, tmp1.reg);
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
// Set tmp2 to -1 if arg < 0, else 0
build.vcmpltsd(tmp2.reg, tmp0.reg, tmp1.reg);
build.vmovsd(tmp3.reg, build.f64(-1));
build.vandpd(tmp2.reg, tmp2.reg, tmp3.reg);
2023-02-03 14:34:12 +02:00
// Set mask bit to 1 if 0 < arg, else 0
2023-03-03 15:45:38 +02:00
build.vcmpltsd(tmp0.reg, tmp1.reg, tmp0.reg);
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
// Result = (mask-bit == 1) ? 1.0 : tmp2
// If arg < 0 then tmp2 is -1 and mask-bit is 0, result is -1
// If arg == 0 then tmp2 is 0 and mask-bit is 0, result is 0
// If arg > 0 then tmp2 is 0 and mask-bit is 1, result is 1
build.vblendvpd(tmp0.reg, tmp2.reg, build.f64x2(1, 1), tmp0.reg);
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
build.vmovsd(luauRegValue(ra), tmp0.reg);
2023-02-03 14:34:12 +02:00
}
2023-03-03 15:45:38 +02:00
void emitBuiltin(IrRegAllocX64& regs, AssemblyBuilderX64& build, int bfid, int ra, int arg, IrOp args, int nparams, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-03 15:45:38 +02:00
OperandX64 argsOp = 0;
2023-02-03 14:34:12 +02:00
2023-03-03 15:45:38 +02:00
if (args.kind == IrOpKind::VmReg)
argsOp = luauRegAddress(args.index);
else if (args.kind == IrOpKind::VmConst)
argsOp = luauConstantAddress(args.index);
2023-02-03 14:34:12 +02:00
2022-10-14 01:59:53 +03:00
switch (bfid)
{
case LBF_ASSERT:
2023-03-03 15:45:38 +02:00
case LBF_MATH_DEG:
case LBF_MATH_RAD:
case LBF_MATH_MIN:
case LBF_MATH_MAX:
case LBF_MATH_CLAMP:
// These instructions are fully translated to IR
break;
2022-10-14 01:59:53 +03:00
case LBF_MATH_FLOOR:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathFloor(regs, build, nparams, ra, arg, argsOp, nresults);
2022-10-14 01:59:53 +03:00
case LBF_MATH_CEIL:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathCeil(regs, build, nparams, ra, arg, argsOp, nresults);
2022-10-14 01:59:53 +03:00
case LBF_MATH_SQRT:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathSqrt(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_ABS:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathAbs(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_EXP:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathExp(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_FMOD:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathFmod(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_POW:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathPow(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_ASIN:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathAsin(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_SIN:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathSin(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_SINH:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathSinh(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_ACOS:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathAcos(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_COS:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathCos(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_COSH:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathCosh(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_ATAN:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathAtan(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_TAN:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathTan(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_TANH:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathTanh(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_ATAN2:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathAtan2(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_LOG10:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathLog10(regs, build, nparams, ra, arg, argsOp, nresults);
2023-01-03 19:33:19 +02:00
case LBF_MATH_LOG:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathLog(regs, build, nparams, ra, arg, argsOp, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_LDEXP:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathLdexp(regs, build, nparams, ra, arg, argsOp, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_ROUND:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathRound(regs, build, nparams, ra, arg, argsOp, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_FREXP:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathFrexp(regs, build, nparams, ra, arg, argsOp, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_MODF:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathModf(regs, build, nparams, ra, arg, argsOp, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_SIGN:
2023-03-03 15:45:38 +02:00
return emitBuiltinMathSign(regs, build, nparams, ra, arg, argsOp, nresults);
2022-10-14 01:59:53 +03:00
default:
2023-03-03 15:45:38 +02:00
LUAU_ASSERT(!"missing x64 lowering");
break;
2022-10-14 01:59:53 +03:00
}
}
2023-03-03 15:45:38 +02:00
} // namespace X64
2022-10-14 01:59:53 +03:00
} // namespace CodeGen
} // namespace Luau