// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details1#pragma once23#include "Luau/AssemblyBuilderA64.h"45#include "EmitCommon.h"67#include "lobject.h"8#include "ltm.h"9#include "lstate.h"1011// AArch64 ABI reminder:12// Arguments: x0-x7, v0-v713// Return: x0, v0 (or x8 that points to the address of the resulting structure)14// Volatile: x9-x15, v16-v31 ("caller-saved", any call may change them)15// Intra-procedure-call temporary: x16-x17 (any call or relocated jump may change them, as linker may point branches to veneers to perform long jumps)16// Non-volatile: x19-x28, v8-v15 ("callee-saved", preserved after calls, only bottom half of SIMD registers is preserved!)17// Reserved: x18: reserved for platform use; x29: frame pointer (unless omitted); x30: link register; x31: stack pointer1819namespace Luau20{21namespace CodeGen22{2324namespace A6425{2627// Data that is very common to access is placed in non-volatile registers:28// 1. Constant registers (only loaded during codegen entry)29inline constexpr RegisterA64 rState = x19; // lua_State* L30inline constexpr RegisterA64 rNativeContext = x20; // NativeContext* context31inline constexpr RegisterA64 rGlobalState = x21; // global_State* L->global3233// 2. Frame registers (reloaded when call frame changes; rBase is also reloaded after all calls that may reallocate stack)34inline constexpr RegisterA64 rConstants = x22; // TValue* k35inline constexpr RegisterA64 rClosure = x23; // Closure* cl36inline constexpr RegisterA64 rCode = x24; // Instruction* code37inline constexpr RegisterA64 rBase = x25; // StkId base3839// Native code is as stackless as the interpreter, so we can place some data on the stack once and have it accessible at any point40// See CodeGenA64.cpp for layout41inline constexpr unsigned kStashSlots = 9; // stashed non-volatile registers42inline constexpr unsigned kTempSlots = 1; // 8 bytes of temporary space, such luxury!43inline constexpr unsigned kSpillSlots = 22; // slots for spilling temporary registers4445static_assert(kSpillSlots % 2 == 0, "spill slots have to be sized in 16 byte TValue chunks, for valid extra register spill-over");46inline constexpr unsigned kExtraSpillSlots = 32;47static_assert(kExtraSpillSlots * 8 <= LUA_EXECUTION_CALLBACK_STORAGE, "can't use more extra slots than Luau global state provides");4849inline constexpr unsigned kStackSize = (kStashSlots + kTempSlots + kSpillSlots) * 8;5051inline constexpr AddressA64 sSpillArea = mem(sp, (kStashSlots + kTempSlots) * 8);52inline constexpr AddressA64 sTemporary = mem(sp, kStashSlots * 8);5354inline void emitUpdateBase(AssemblyBuilderA64& build)55{56build.ldr(rBase, mem(rState, offsetof(lua_State, base)));57}5859} // namespace A6460} // namespace CodeGen61} // namespace Luau626364