luau/CodeGen/src/EmitBuiltinsX64.cpp

112 lines
3.5 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/Bytecode.h"
2023-08-11 15:55:30 +03:00
#include "Luau/AssemblyBuilderX64.h"
2023-03-31 15:21:14 +03:00
#include "Luau/IrCallWrapperX64.h"
#include "Luau/IrRegAllocX64.h"
2022-10-14 01:59:53 +03:00
#include "EmitCommonX64.h"
2023-01-03 19:33:19 +02:00
#include "NativeState.h"
2022-10-14 01:59:53 +03:00
#include "lstate.h"
2024-06-28 17:07:35 -07:00
LUAU_FASTFLAG(LuauCodegenMathSign)
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-04-28 14:55:55 +03:00
static void emitBuiltinMathFrexp(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-31 15:21:14 +03:00
IrCallWrapperX64 callWrap(regs, build);
callWrap.addArgument(SizeX64::xmmword, luauRegValue(arg));
callWrap.addArgument(SizeX64::qword, sTemporarySlot);
callWrap.call(qword[rNativeContext + offsetof(NativeContext, libm_frexp)]);
2023-02-03 14:34:12 +02:00
build.vmovsd(luauRegValue(ra), xmm0);
2024-06-21 01:23:57 +03:00
build.mov(luauRegTag(ra), LUA_TNUMBER);
2024-03-15 14:01:00 -07:00
2023-04-07 12:56:27 -07:00
if (nresults > 1)
{
build.vcvtsi2sd(xmm0, xmm0, dword[sTemporarySlot + 0]);
build.vmovsd(luauRegValue(ra + 1), xmm0);
2024-06-21 01:23:57 +03:00
build.mov(luauRegTag(ra + 1), LUA_TNUMBER);
2023-04-07 12:56:27 -07:00
}
2023-02-03 14:34:12 +02:00
}
2023-04-28 14:55:55 +03:00
static void emitBuiltinMathModf(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg, int nresults)
2023-02-03 14:34:12 +02:00
{
2023-03-31 15:21:14 +03:00
IrCallWrapperX64 callWrap(regs, build);
callWrap.addArgument(SizeX64::xmmword, luauRegValue(arg));
callWrap.addArgument(SizeX64::qword, sTemporarySlot);
callWrap.call(qword[rNativeContext + offsetof(NativeContext, libm_modf)]);
2023-02-03 14:34:12 +02:00
build.vmovsd(xmm1, qword[sTemporarySlot + 0]);
build.vmovsd(luauRegValue(ra), xmm1);
2024-06-21 01:23:57 +03:00
build.mov(luauRegTag(ra), LUA_TNUMBER);
2024-03-15 14:01:00 -07:00
2023-04-07 12:56:27 -07:00
if (nresults > 1)
2024-03-15 14:01:00 -07:00
{
2023-04-07 12:56:27 -07:00
build.vmovsd(luauRegValue(ra + 1), xmm0);
2024-06-21 01:23:57 +03:00
build.mov(luauRegTag(ra + 1), LUA_TNUMBER);
2024-03-15 14:01:00 -07:00
}
2023-02-03 14:34:12 +02:00
}
2023-04-28 14:55:55 +03:00
static void emitBuiltinMathSign(IrRegAllocX64& regs, AssemblyBuilderX64& build, int ra, int arg)
2023-02-03 14:34:12 +02:00
{
2024-06-28 17:07:35 -07:00
CODEGEN_ASSERT(!FFlag::LuauCodegenMathSign);
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);
2024-06-21 01:23:57 +03:00
build.mov(luauRegTag(ra), LUA_TNUMBER);
2023-02-03 14:34:12 +02:00
}
2024-06-21 01:23:57 +03:00
void emitBuiltin(IrRegAllocX64& regs, AssemblyBuilderX64& build, int bfid, int ra, int arg, int nresults)
2023-02-03 14:34:12 +02:00
{
2022-10-14 01:59:53 +03:00
switch (bfid)
{
2023-02-03 14:34:12 +02:00
case LBF_MATH_FREXP:
2024-06-21 01:23:57 +03:00
CODEGEN_ASSERT(nresults == 1 || nresults == 2);
2023-04-28 14:55:55 +03:00
return emitBuiltinMathFrexp(regs, build, ra, arg, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_MODF:
2024-06-21 01:23:57 +03:00
CODEGEN_ASSERT(nresults == 1 || nresults == 2);
2023-04-28 14:55:55 +03:00
return emitBuiltinMathModf(regs, build, ra, arg, nresults);
2023-02-03 14:34:12 +02:00
case LBF_MATH_SIGN:
2024-06-28 17:07:35 -07:00
CODEGEN_ASSERT(!FFlag::LuauCodegenMathSign);
2024-06-21 01:23:57 +03:00
CODEGEN_ASSERT(nresults == 1);
2023-04-28 14:55:55 +03:00
return emitBuiltinMathSign(regs, build, ra, arg);
2022-10-14 01:59:53 +03:00
default:
2024-02-16 03:25:31 +02:00
CODEGEN_ASSERT(!"Missing x64 lowering");
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