Function

Function definitions.

Overview

AsmJit provides functionality that can be used to define function signatures and to calculate automatically optimal function frame that can be used directly by a prolog and epilog insertion. This feature was exclusive to AsmJit's Compiler for a very long time, but was abstracted out and is now available for all users regardless of the emitter they use. The following use cases are possible:

  • Calculate function frame before the function is generated - this is the only way available to BaseAssembler users and it will be described in this section.
  • Calculate function frame after the function is generated - this way is generally used by BaseBuilder and BaseCompiler emitters and this way is generally described in Compiler section.

The following concepts are used to describe and create functions in AsmJit:

  • TypeId - Type-id is an 8-bit value that describes a platform independent type as we know from C/C++. It provides abstractions for most common types like int8_t, uint32_t, uintptr_t, float, double, and all possible vector types to match ISAs up to AVX512. TypeId was introduced originally for Compiler, but it's now used by FuncSignature as well.
  • CallConv - Describes a calling convention - this class contains instructions to assign registers and stack addresses to function arguments and return value(s), but doesn't specify any function signature itself. Calling conventions are architecture and OS dependent.
  • FuncSignature - Describes a function signature, for example int func(int, int). FuncSignature contains a function calling convention id, return value type, and function arguments. The signature itself is platform independent and uses TypeId to describe types of function arguments and function return value(s).
  • FuncDetail - Architecture and ABI dependent information that describes CallConv and expanded FuncSignature. Each function argument and return value is represented as FuncValue that contains the original TypeId enriched with additional information that specifies whether the value is passed or returned by register (and which register) or by stack. Each value also contains some other metadata that provide additional information required to handle it properly (for example whether a vector is passed indirectly by a pointer as required by WIN64 calling convention).
  • FuncFrame - Contains information about the function frame that can be used by prolog/epilog inserter (PEI). Holds call stack size size and alignment, local stack size and alignment, and various attributes that describe how prolog and epilog should be constructed. FuncFrame doesn't know anything about function's arguments or return values, it hold only information necessary to create a valid and ABI conforming function prologs and epilogs.
  • FuncArgsAssignment - A helper class that can be used to reassign function arguments into user specified registers. It's architecture and ABI dependent mapping from function arguments described by CallConv and FuncDetail into registers specified by the user.

It's a lot of concepts where each represents one step in a function frame calculation. It can be used to create function prologs, epilogs, and also to calculate information necessary to perform function calls.

Classes

Enumerations

Enumeration Type Documentation

class CallConvId : uint8_tenumstrong◆ 

Calling convention id.

Calling conventions can be divided into the following groups:

  • Universal - calling conventions are applicable to any target. They will be converted to a target dependent calling convention at runtime by CallConv::init() with some help from Environment. The purpose of these calling conventions is to make using functions less target dependent and closer to C and C++.
  • Target specific - calling conventions that are used by a particular architecture and ABI. For example Windows 64-bit calling convention and AMD64 SystemV calling convention.
ConstantDescription
kCDecl 

Standard function call or explicit __cdecl where it can be specified.

This is a universal calling convention, which is used to initialize specific calling conventions based on architecture, platform, and its ABI.

kStdCall 

__stdcall on targets that support this calling convention (X86).

Note
This calling convention is only supported on 32-bit X86. If used on environment that doesn't support this calling convention it will be replaced by CallConvId::kCDecl.
kFastCall 

__fastcall on targets that support this calling convention (X86).

Note
This calling convention is only supported on 32-bit X86. If used on environment that doesn't support this calling convention it will be replaced by CallConvId::kCDecl.
kVectorCall 

__vectorcall on targets that support this calling convention (X86/X64).

Note
This calling convention is only supported on 32-bit and 64-bit X86 architecture on Windows platform. If used on environment that doesn't support this calling it will be replaced by CallConvId::kCDecl.
kThisCall 

__thiscall on targets that support this calling convention (X86).

Note
This calling convention is only supported on 32-bit X86 Windows platform. If used on environment that doesn't support this calling convention it will be replaced by CallConvId::kCDecl.
kRegParm1 

__attribute__((regparm(1))) convention (GCC and Clang).

kRegParm2 

__attribute__((regparm(2))) convention (GCC and Clang).

kRegParm3 

__attribute__((regparm(3))) convention (GCC and Clang).

kLightCall2 

AsmJit specific calling convention designed for calling functions inside a multimedia code that don't use many registers internally, but are long enough to be called and not inlined.

These functions are usually used to calculate trigonometric functions, logarithms, etc...

kSoftFloat 

Soft-float calling convention (AArch32).

Floating point arguments are passed via general purpose registers.

kHardFloat 

Hard-float calling convention (AArch32).

Floating point arguments are passed via SIMD registers.

kX64SystemV 

X64 System-V calling convention.

kX64Windows 

X64 Windows calling convention.

kMaxValue 

Maximum value of CallConvId.

class CallConvStrategy : uint8_tenumstrong◆ 

Strategy used by calling conventions to assign registers to function arguments.

Calling convention strategy describes how AsmJit should convert function arguments used by FuncSignature into register identifiers and stack offsets. The CallConvStrategy::kDefault strategy assigns registers and then stack whereas CallConvStrategy::kX64Windows strategy does register shadowing as defined by WIN64 calling convention, which is only used by 64-bit Windows.

ConstantDescription
kDefault 

Default register assignment strategy.

kX64Windows 

Windows 64-bit ABI register assignment strategy.

kX64VectorCall 

Windows 64-bit __vectorcall register assignment strategy.

kMaxValue 

Maximum value of CallConvStrategy.

class CallConvFlags : uint32_tenumstrong◆ 

Calling convention flags.

ConstantDescription
kNone 

No flags.

kCalleePopsStack 

Callee is responsible for cleaning up the stack.

kIndirectVecArgs 

Pass vector arguments indirectly (as a pointer).

kPassFloatsByVec 

Pass F32 and F64 arguments via VEC128 register.

kPassVecByStackIfVA 

Pass MMX and vector arguments via stack if the function has variable arguments.

kPassMmxByGp 

MMX registers are passed and returned via GP registers.

kPassMmxByXmm 

MMX registers are passed and returned via XMM registers.

kVarArgCompatible 

Calling convention can be used with variable arguments.

class FuncAttributes : uint32_tenumstrong◆ 

Attributes are designed in a way that all are initially false, and user or FuncFrame finalizer adds them when necessary.

ConstantDescription
kNoAttributes 

No attributes.

kHasVarArgs 

Function has variable number of arguments.

kHasPreservedFP 

Preserve frame pointer (don't omit FP).

kHasFuncCalls 

Function calls other functions (is not leaf).

kAlignedVecSR 

Function has aligned save/restore of vector registers.

kIndirectBranchProtection 

Function must begin with an instruction that marks a start of a branch or function.

* `ENDBR32/ENDBR64` instruction is inserted at the beginning of the function (X86, X86_64).
* `BTI` instruction is inserted at the beginning of the function (AArch64) 
kIsFinalized 

FuncFrame is finalized and can be used by prolog/epilog inserter (PEI).

kX86_AVXEnabled 

Enables the use of AVX within the function's body, prolog, and epilog (X86).

This flag instructs prolog and epilog emitter to use AVX instead of SSE for manipulating XMM registers.

kX86_AVX512Enabled 

Enables the use of AVX-512 within the function's body, prolog, and epilog (X86).

This flag instructs Compiler register allocator to use additional 16 registers introduced by AVX-512. Additionally, if the functions saves full width of ZMM registers (custom calling conventions only) then the prolog/epilog inserter would use AVX-512 move instructions to emit the save and restore sequence.

kX86_MMXCleanup 

This flag instructs the epilog writer to emit EMMS instruction before RET (X86).

kX86_AVXCleanup 

This flag instructs the epilog writer to emit VZEROUPPER instruction before RET (X86).