module volt.llvm.abi.base

Perform ABI modifications to functions and function calls, if needed.

This layer dispatches to the appropriate platform specific function.

Code Map

//! Perform ABI modifications to functions and function calls, if needed.
module volt.llvm.abi.base;


enum NotCoerced;
enum Coerced;

alias CoercedStatus = bool;

//! If the target platform and this function needs it, modify to match the
//! ABI.
fn abiCoerceParameters(state: State, ft: ir.FunctionType, retType: LLVMTypeRef, params: LLVMTypeRef[]) { }
//! If the parameters for the given function were modified, modify the
//! call to match.
fn abiCoerceArguments(state: State, ct: ir.CallableType, params: LLVMValueRef[]) { }
//! Coerce the prologue section of the function.
fn abiCoercePrologueParameter(state: State, llvmFunc: LLVMValueRef, func: ir.Function, ct: ir.CallableType, val: LLVMValueRef, index: size_t, offset: size_t) CoercedStatus { }
fn buildGep(state: State, ptr: LLVMValueRef, a: u64, b: u64) LLVMValueRef { }
fn abiCoerceParameters(state: State, ft: ir.FunctionType, retType: LLVMTypeRef, params: LLVMTypeRef[])

If the target platform and this function needs it, modify to match the ABI.

If we're running on a target that needs to modify functions in someway, and ft matches those functions, modify params as needed.

fn abiCoerceArguments(state: State, ct: ir.CallableType, params: LLVMValueRef[])

If the parameters for the given function were modified, modify the call to match.

fn abiCoercePrologueParameter(state: State, llvmFunc: LLVMValueRef, func: ir.Function, ct: ir.CallableType, val: LLVMValueRef, index: size_t, offset: size_t) CoercedStatus

Coerce the prologue section of the function.

The prologue is at the top, where parameters are assigned into locals.
This function is a little less 'set and forget' than the other two coerce functions; it needs to be called in the loop, and an index variable needs to be used in your parameter lookups.
The reason is that removing generated code is fragile (as that code could change, and someone might not be aware that this function relies on the output) and more complicated than modifying a list of LLVMValues or LLVMTypes.

This is intended to be called where the simple LLVMBuildStore would go in the prologue generation.

Parameters

state

The State instance, to access the builder and context.

llvmFunc

The LLVM function that we are modifying.

func

The IR function that we are modifying.

ct

The CallableType with abiData on it.

val

The LLVMValueRef retrieved from LLVMGetParam.

index

The index of the for loop -- which parameter we're looking at, not counting offset.

offset

Start with a size_t initialised to 0, and add it to your LLVMGetParam call. (This is so we can insert parameters without having to modify every list of parameters that exist in the IR).

Return

true if something was coerced and no further action should be taken on this parameter. If false, caller should call the LLVMBuildStore path that is usually taken.