mirror of
https://github.com/luau-lang/luau.git
synced 2025-02-01 07:13:09 +00:00
110 lines
3.3 KiB
C++
110 lines
3.3 KiB
C++
|
// 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"
|
||
|
|
||
|
#include "lstate.h"
|
||
|
|
||
|
namespace Luau
|
||
|
{
|
||
|
namespace CodeGen
|
||
|
{
|
||
|
|
||
|
BuiltinImplResult emitBuiltinAssert(AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults, Label& fallback)
|
||
|
{
|
||
|
if (nparams < 1 || nresults != 0)
|
||
|
return {BuiltinImplType::None, -1};
|
||
|
|
||
|
if (build.logText)
|
||
|
build.logAppend("; inlined LBF_ASSERT\n");
|
||
|
|
||
|
Label skip;
|
||
|
|
||
|
jumpIfFalsy(build, arg, fallback, skip);
|
||
|
|
||
|
// TODO: use of 'skip' causes a jump to a jump instruction that skips the fallback - can be optimized
|
||
|
build.setLabel(skip);
|
||
|
|
||
|
return {BuiltinImplType::UsesFallback, 0};
|
||
|
}
|
||
|
|
||
|
BuiltinImplResult emitBuiltinMathFloor(AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults, Label& fallback)
|
||
|
{
|
||
|
if (nparams < 1 || nresults > 1)
|
||
|
return {BuiltinImplType::None, -1};
|
||
|
|
||
|
if (build.logText)
|
||
|
build.logAppend("; inlined LBF_MATH_FLOOR\n");
|
||
|
|
||
|
jumpIfTagIsNot(build, arg, LUA_TNUMBER, fallback);
|
||
|
|
||
|
build.vroundsd(xmm0, xmm0, luauRegValue(arg), RoundingModeX64::RoundToNegativeInfinity);
|
||
|
build.vmovsd(luauRegValue(ra), xmm0);
|
||
|
|
||
|
if (ra != arg)
|
||
|
build.mov(luauRegTag(ra), LUA_TNUMBER);
|
||
|
|
||
|
return {BuiltinImplType::UsesFallback, 1};
|
||
|
}
|
||
|
|
||
|
BuiltinImplResult emitBuiltinMathCeil(AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults, Label& fallback)
|
||
|
{
|
||
|
if (nparams < 1 || nresults > 1)
|
||
|
return {BuiltinImplType::None, -1};
|
||
|
|
||
|
if (build.logText)
|
||
|
build.logAppend("; inlined LBF_MATH_CEIL\n");
|
||
|
|
||
|
jumpIfTagIsNot(build, arg, LUA_TNUMBER, fallback);
|
||
|
|
||
|
build.vroundsd(xmm0, xmm0, luauRegValue(arg), RoundingModeX64::RoundToPositiveInfinity);
|
||
|
build.vmovsd(luauRegValue(ra), xmm0);
|
||
|
|
||
|
if (ra != arg)
|
||
|
build.mov(luauRegTag(ra), LUA_TNUMBER);
|
||
|
|
||
|
return {BuiltinImplType::UsesFallback, 1};
|
||
|
}
|
||
|
|
||
|
BuiltinImplResult emitBuiltinMathSqrt(AssemblyBuilderX64& build, int nparams, int ra, int arg, OperandX64 args, int nresults, Label& fallback)
|
||
|
{
|
||
|
if (nparams < 1 || nresults > 1)
|
||
|
return {BuiltinImplType::None, -1};
|
||
|
|
||
|
if (build.logText)
|
||
|
build.logAppend("; inlined LBF_MATH_SQRT\n");
|
||
|
|
||
|
jumpIfTagIsNot(build, arg, LUA_TNUMBER, fallback);
|
||
|
|
||
|
build.vsqrtsd(xmm0, xmm0, luauRegValue(arg));
|
||
|
build.vmovsd(luauRegValue(ra), xmm0);
|
||
|
|
||
|
if (ra != arg)
|
||
|
build.mov(luauRegTag(ra), LUA_TNUMBER);
|
||
|
|
||
|
return {BuiltinImplType::UsesFallback, 1};
|
||
|
}
|
||
|
|
||
|
BuiltinImplResult emitBuiltin(AssemblyBuilderX64& build, int bfid, int nparams, int ra, int arg, OperandX64 args, int nresults, Label& fallback)
|
||
|
{
|
||
|
switch (bfid)
|
||
|
{
|
||
|
case LBF_ASSERT:
|
||
|
return emitBuiltinAssert(build, nparams, ra, arg, args, nresults, fallback);
|
||
|
case LBF_MATH_FLOOR:
|
||
|
return emitBuiltinMathFloor(build, nparams, ra, arg, args, nresults, fallback);
|
||
|
case LBF_MATH_CEIL:
|
||
|
return emitBuiltinMathCeil(build, nparams, ra, arg, args, nresults, fallback);
|
||
|
case LBF_MATH_SQRT:
|
||
|
return emitBuiltinMathSqrt(build, nparams, ra, arg, args, nresults, fallback);
|
||
|
default:
|
||
|
return {BuiltinImplType::None, -1};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // namespace CodeGen
|
||
|
} // namespace Luau
|