// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #pragma once #include "Luau/AssemblyBuilderX64.h" #include "Luau/IrData.h" #include "Luau/OperandX64.h" #include "Luau/RegisterX64.h" #include // TODO: call wrapper can be used to suggest target registers for ScopedRegX64 to compute data into argument registers directly namespace Luau { namespace CodeGen { namespace X64 { struct IrRegAllocX64; struct ScopedRegX64; struct CallArgument { SizeX64 targetSize = SizeX64::none; OperandX64 source = noreg; IrOp sourceOp; OperandX64 target = noreg; bool candidate = true; }; class IrCallWrapperX64 { public: IrCallWrapperX64(IrRegAllocX64& regs, AssemblyBuilderX64& build, uint32_t instIdx = kInvalidInstIdx); void addArgument(SizeX64 targetSize, OperandX64 source, IrOp sourceOp = {}); void addArgument(SizeX64 targetSize, ScopedRegX64& scopedReg); void call(const OperandX64& func); RegisterX64 suggestNextArgumentRegister(SizeX64 size) const; IrRegAllocX64& regs; AssemblyBuilderX64& build; uint32_t instIdx = ~0u; private: OperandX64 getNextArgumentTarget(SizeX64 size) const; void countRegisterUses(); CallArgument* findNonInterferingArgument(); bool interferesWithOperand(const OperandX64& op, RegisterX64 reg) const; bool interferesWithActiveSources(const CallArgument& targetArg, int targetArgIndex) const; bool interferesWithActiveTarget(RegisterX64 sourceReg) const; void moveToTarget(CallArgument& arg); void freeSourceRegisters(CallArgument& arg); void renameRegister(RegisterX64& target, RegisterX64 reg, RegisterX64 replacement); void renameSourceRegisters(RegisterX64 reg, RegisterX64 replacement); RegisterX64 findConflictingTarget() const; void renameConflictingRegister(RegisterX64 conflict); int getRegisterUses(RegisterX64 reg) const; void addRegisterUse(RegisterX64 reg); void removeRegisterUse(RegisterX64 reg); static const int kMaxCallArguments = 6; std::array args; int argCount = 0; int gprPos = 0; int xmmPos = 0; OperandX64 funcOp; // Internal counters for remaining register use counts std::array gprUses; std::array xmmUses; }; } // namespace X64 } // namespace CodeGen } // namespace Luau