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:
- Type::Id - 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
double, and all possible vector types to match ISAs up to AVX512. Type::Id 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 Type::Id 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 Type::Id 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.