infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
abi_arm64.c File Reference

Implements the FFI logic for the AArch64 (ARM64) architecture. More...

#include "abi_arm64_common.h"
#include "abi_arm64_emitters.h"
#include "common/infix_internals.h"
#include "common/utility.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for abi_arm64.c:

Macros

#define NUM_GPR_ARGS   8
 
#define NUM_VPR_ARGS   8
 
#define MAX_AGGREGATE_FIELDS_TO_CLASSIFY   32
 

Functions

static infix_status prepare_forward_call_frame_arm64 (infix_arena_t *arena, infix_call_frame_layout **out_layout, infix_type *ret_type, infix_type **arg_types, size_t num_args, size_t num_fixed_args, void *target_fn)
 
static infix_status generate_forward_prologue_arm64 (code_buffer *buf, infix_call_frame_layout *layout)
 
static infix_status generate_forward_argument_moves_arm64 (code_buffer *buf, infix_call_frame_layout *layout, infix_type **arg_types, size_t num_args, c23_maybe_unused size_t num_fixed_args)
 
static infix_status generate_forward_call_instruction_arm64 (code_buffer *, infix_call_frame_layout *)
 
static infix_status generate_forward_epilogue_arm64 (code_buffer *buf, infix_call_frame_layout *layout, infix_type *ret_type)
 
static bool is_hfa (infix_type *type, infix_type **base_type)
 
static infix_status prepare_reverse_call_frame_arm64 (infix_arena_t *arena, infix_reverse_call_frame_layout **out_layout, infix_reverse_t *context)
 
static infix_status generate_reverse_prologue_arm64 (code_buffer *buf, infix_reverse_call_frame_layout *layout)
 
static infix_status generate_reverse_argument_marshalling_arm64 (code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
 
static infix_status generate_reverse_dispatcher_call_arm64 (code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
 
static infix_status generate_reverse_epilogue_arm64 (code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
 
static infix_typeget_hfa_base_type (infix_type *type)
 
static bool is_hfa_recursive_check (infix_type *type, infix_type *base_type, size_t *field_count)
 
static infix_status generate_forward_call_instruction_arm64 (code_buffer *buf, c23_maybe_unused infix_call_frame_layout *layout)
 

Variables

static const arm64_gpr GPR_ARGS [] = {X0_REG, X1_REG, X2_REG, X3_REG, X4_REG, X5_REG, X6_REG, X7_REG}
 
static const arm64_vpr VPR_ARGS [] = {V0_REG, V1_REG, V2_REG, V3_REG, V4_REG, V5_REG, V6_REG, V7_REG}
 
const infix_forward_abi_spec g_arm64_forward_spec
 
const infix_reverse_abi_spec g_arm64_reverse_spec
 

Detailed Description

Implements the FFI logic for the AArch64 (ARM64) architecture.

Copyright (c) 2025 Sanko Robinson

This source code is dual-licensed under the Artistic License 2.0 or the MIT License. You may choose to use this code under the terms of either license.

SPDX-License-Identifier: (Artistic-2.0 OR MIT)

The documentation blocks within this file are licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).

SPDX-License-Identifier: CC-BY-4.0

Macro Definition Documentation

◆ MAX_AGGREGATE_FIELDS_TO_CLASSIFY

#define MAX_AGGREGATE_FIELDS_TO_CLASSIFY   32

A safe limit on the number of fields to classify to prevent DoS from exponential complexity.

◆ NUM_GPR_ARGS

#define NUM_GPR_ARGS   8

The total number of GPRs available for argument passing.

◆ NUM_VPR_ARGS

#define NUM_VPR_ARGS   8

The total number of VPRs available for argument passing.

Function Documentation

◆ generate_forward_argument_moves_arm64()

static infix_status generate_forward_argument_moves_arm64 ( code_buffer buf,
infix_call_frame_layout layout,
infix_type **  arg_types,
size_t  num_args,
c23_maybe_unused size_t  num_fixed_args 
)
static

◆ generate_forward_call_instruction_arm64() [1/2]

static infix_status generate_forward_call_instruction_arm64 ( code_buffer ,
infix_call_frame_layout  
)
static

◆ generate_forward_call_instruction_arm64() [2/2]

static infix_status generate_forward_call_instruction_arm64 ( code_buffer buf,
c23_maybe_unused infix_call_frame_layout layout 
)
static

◆ generate_forward_epilogue_arm64()

static infix_status generate_forward_epilogue_arm64 ( code_buffer buf,
infix_call_frame_layout layout,
infix_type ret_type 
)
static

◆ generate_forward_prologue_arm64()

static infix_status generate_forward_prologue_arm64 ( code_buffer buf,
infix_call_frame_layout layout 
)
static

◆ generate_reverse_argument_marshalling_arm64()

static infix_status generate_reverse_argument_marshalling_arm64 ( code_buffer buf,
infix_reverse_call_frame_layout layout,
infix_reverse_t context 
)
static

◆ generate_reverse_dispatcher_call_arm64()

static infix_status generate_reverse_dispatcher_call_arm64 ( code_buffer buf,
infix_reverse_call_frame_layout layout,
infix_reverse_t context 
)
static

◆ generate_reverse_epilogue_arm64()

static infix_status generate_reverse_epilogue_arm64 ( code_buffer buf,
infix_reverse_call_frame_layout layout,
infix_reverse_t context 
)
static

◆ generate_reverse_prologue_arm64()

static infix_status generate_reverse_prologue_arm64 ( code_buffer buf,
infix_reverse_call_frame_layout layout 
)
static

◆ get_hfa_base_type()

static infix_type * get_hfa_base_type ( infix_type type)
static

◆ is_hfa()

static bool is_hfa ( infix_type type,
infix_type **  base_type 
)
static

◆ is_hfa_recursive_check()

static bool is_hfa_recursive_check ( infix_type type,
infix_type base_type,
size_t *  field_count 
)
static

◆ prepare_forward_call_frame_arm64()

static infix_status prepare_forward_call_frame_arm64 ( infix_arena_t arena,
infix_call_frame_layout **  out_layout,
infix_type ret_type,
infix_type **  arg_types,
size_t  num_args,
size_t  num_fixed_args,
void *  target_fn 
)
static

◆ prepare_reverse_call_frame_arm64()

static infix_status prepare_reverse_call_frame_arm64 ( infix_arena_t arena,
infix_reverse_call_frame_layout **  out_layout,
infix_reverse_t context 
)
static

Variable Documentation

◆ g_arm64_forward_spec

const infix_forward_abi_spec g_arm64_forward_spec
Initial value:
= {
.prepare_forward_call_frame = prepare_forward_call_frame_arm64,
.generate_forward_prologue = generate_forward_prologue_arm64,
.generate_forward_argument_moves = generate_forward_argument_moves_arm64,
.generate_forward_call_instruction = generate_forward_call_instruction_arm64,
.generate_forward_epilogue = generate_forward_epilogue_arm64}
static infix_status generate_forward_argument_moves_arm64(code_buffer *buf, infix_call_frame_layout *layout, infix_type **arg_types, size_t num_args, c23_maybe_unused size_t num_fixed_args)
Definition abi_arm64.c:440
static infix_status generate_forward_call_instruction_arm64(code_buffer *, infix_call_frame_layout *)
static infix_status generate_forward_prologue_arm64(code_buffer *buf, infix_call_frame_layout *layout)
Definition abi_arm64.c:407
static infix_status prepare_forward_call_frame_arm64(infix_arena_t *arena, infix_call_frame_layout **out_layout, infix_type *ret_type, infix_type **arg_types, size_t num_args, size_t num_fixed_args, void *target_fn)
Definition abi_arm64.c:241
static infix_status generate_forward_epilogue_arm64(code_buffer *buf, infix_call_frame_layout *layout, infix_type *ret_type)
Definition abi_arm64.c:611

◆ g_arm64_reverse_spec

const infix_reverse_abi_spec g_arm64_reverse_spec
Initial value:
= {
.prepare_reverse_call_frame = prepare_reverse_call_frame_arm64,
.generate_reverse_prologue = generate_reverse_prologue_arm64,
.generate_reverse_argument_marshalling = generate_reverse_argument_marshalling_arm64,
.generate_reverse_dispatcher_call = generate_reverse_dispatcher_call_arm64,
.generate_reverse_epilogue = generate_reverse_epilogue_arm64}
static infix_status generate_reverse_argument_marshalling_arm64(code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
Definition abi_arm64.c:749
static infix_status generate_reverse_dispatcher_call_arm64(code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
Definition abi_arm64.c:969
static infix_status generate_reverse_prologue_arm64(code_buffer *buf, infix_reverse_call_frame_layout *layout)
Definition abi_arm64.c:729
static infix_status prepare_reverse_call_frame_arm64(infix_arena_t *arena, infix_reverse_call_frame_layout **out_layout, infix_reverse_t *context)
Definition abi_arm64.c:670
static infix_status generate_reverse_epilogue_arm64(code_buffer *buf, infix_reverse_call_frame_layout *layout, infix_reverse_t *context)
Definition abi_arm64.c:1006

◆ GPR_ARGS

const arm64_gpr GPR_ARGS[] = {X0_REG, X1_REG, X2_REG, X3_REG, X4_REG, X5_REG, X6_REG, X7_REG}
static

The General-Purpose Registers used for the first 8 integer/pointer arguments.

◆ VPR_ARGS

const arm64_vpr VPR_ARGS[] = {V0_REG, V1_REG, V2_REG, V3_REG, V4_REG, V5_REG, V6_REG, V7_REG}
static

The SIMD/Floating-Point Registers used for the first 8 float/double/vector arguments.