kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 7484601482123847d836cc711d250f7cbef65d46
parent e16a6ff438645bc74c6d4945681f8874801fc981
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 26 May 2026 15:41:07 -0700

abi: add va_list layout details per target

Add ABIVaListInfo/ABIVaListKind and abi_va_list_layout() to describe the
in-memory layout of __builtin_va_list for each ABI.  AAPCS64 gets the full
struct layout (stack/gr_top/vr_top/gr_offs/vr_offs fields and register
counts); SysV x64 and Apple x64 get their register-save-area layout; pointer
and Windows ABIs get the POINTER kind.

Auto-upgrade OPAQUE to POINTER when the underlying type is a scalar pointer,
so targets that don't need the detailed layout can stay OPAQUE and still
provide a useful fallback.

Diffstat:
Msrc/abi/abi.c | 10++++++++++
Msrc/abi/abi.h | 23+++++++++++++++++++++++
Msrc/abi/abi_aapcs64.c | 12++++++++++++
Msrc/abi/abi_aapcs64_windows.c | 2++
Msrc/abi/abi_apple_arm64.c | 2++
Msrc/abi/abi_apple_x64.c | 11+++++++++++
Msrc/abi/abi_internal.h | 1+
Msrc/abi/abi_rv64.c | 2++
Msrc/abi/abi_sysv_x64.c | 11+++++++++++
Msrc/abi/abi_win64_x64.c | 2++
10 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/src/abi/abi.c b/src/abi/abi.c @@ -168,6 +168,16 @@ const ABIFuncInfo* abi_cg_func_info(TargetABI* a, CfreeCgTypeId fn_type) { ABITypeInfo abi_va_list_info(TargetABI* a) { return a->vt->va_list_info; } +ABIVaListInfo abi_va_list_layout(TargetABI* a) { + ABIVaListInfo out = a->vt->va_list_layout; + if (out.kind == ABI_VA_LIST_OPAQUE) { + out.type = a->vt->va_list_info; + if (out.type.scalar_kind == ABI_SC_PTR && out.type.size == 8u) + out.kind = ABI_VA_LIST_POINTER; + } + return out; +} + /* ---- lifecycle ---- */ static const ABIVtable* select_vtable(Compiler* c) { diff --git a/src/abi/abi.h b/src/abi/abi.h @@ -27,6 +27,28 @@ typedef struct ABITypeInfo { u8 pad; } ABITypeInfo; +typedef enum ABIVaListKind { + ABI_VA_LIST_OPAQUE, + ABI_VA_LIST_POINTER, + ABI_VA_LIST_AAPCS64, + ABI_VA_LIST_SYSV_X64, +} ABIVaListKind; + +typedef struct ABIVaListInfo { + ABITypeInfo type; + u8 kind; /* ABIVaListKind */ + u8 pad[3]; + u32 stack_offset; + u32 gr_top_offset; + u32 vr_top_offset; + u32 gr_offs_offset; + u32 vr_offs_offset; + u32 gp_reg_count; + u32 fp_reg_count; + u32 gp_slot_size; + u32 fp_slot_size; +} ABIVaListInfo; + typedef struct ABIFieldLayout { u32 offset; /* byte offset from record base */ u16 bit_offset; /* bit offset within storage unit for bitfields */ @@ -122,5 +144,6 @@ u32 abi_cg_alignof(TargetABI*, CfreeCgTypeId); const ABIRecordLayout* abi_cg_record_layout(TargetABI*, CfreeCgTypeId); const ABIFuncInfo* abi_cg_func_info(TargetABI*, CfreeCgTypeId fn_type); ABITypeInfo abi_va_list_info(TargetABI*); +ABIVaListInfo abi_va_list_layout(TargetABI*); #endif diff --git a/src/abi/abi_aapcs64.c b/src/abi/abi_aapcs64.c @@ -144,4 +144,16 @@ ABIFuncInfo* aapcs64_compute_func_info(TargetABI* a, CfreeCgTypeId fn) { const ABIVtable aapcs64_vtable = { .compute_func_info = aapcs64_compute_func_info, .va_list_info = {32, 8, ABI_SC_VOID, 0, 0, 0}, + .va_list_layout = + {.type = {32, 8, ABI_SC_VOID, 0, 0, 0}, + .kind = ABI_VA_LIST_AAPCS64, + .stack_offset = 0, + .gr_top_offset = 8, + .vr_top_offset = 16, + .gr_offs_offset = 24, + .vr_offs_offset = 28, + .gp_reg_count = 8, + .fp_reg_count = 8, + .gp_slot_size = 8, + .fp_slot_size = 16}, }; diff --git a/src/abi/abi_aapcs64_windows.c b/src/abi/abi_aapcs64_windows.c @@ -63,4 +63,6 @@ static ABIFuncInfo* aapcs64_windows_compute_func_info(TargetABI* a, const ABIVtable aapcs64_windows_vtable = { .compute_func_info = aapcs64_windows_compute_func_info, .va_list_info = {8, 8, ABI_SC_PTR, 0, 0, 0}, + .va_list_layout = + {.type = {8, 8, ABI_SC_PTR, 0, 0, 0}, .kind = ABI_VA_LIST_POINTER}, }; diff --git a/src/abi/abi_apple_arm64.c b/src/abi/abi_apple_arm64.c @@ -45,4 +45,6 @@ static ABIFuncInfo* apple_arm64_compute_func_info(TargetABI* a, const ABIVtable apple_arm64_vtable = { .compute_func_info = apple_arm64_compute_func_info, .va_list_info = {8, 8, ABI_SC_PTR, 0, 0, 0}, + .va_list_layout = + {.type = {8, 8, ABI_SC_PTR, 0, 0, 0}, .kind = ABI_VA_LIST_POINTER}, }; diff --git a/src/abi/abi_apple_x64.c b/src/abi/abi_apple_x64.c @@ -18,4 +18,15 @@ static ABIFuncInfo* apple_x64_compute_func_info(TargetABI* a, const ABIVtable apple_x64_vtable = { .compute_func_info = apple_x64_compute_func_info, .va_list_info = {24, 8, ABI_SC_VOID, 0, 0, 0}, + .va_list_layout = + {.type = {24, 8, ABI_SC_VOID, 0, 0, 0}, + .kind = ABI_VA_LIST_SYSV_X64, + .stack_offset = 8, + .gr_top_offset = 16, + .gr_offs_offset = 0, + .vr_offs_offset = 4, + .gp_reg_count = 6, + .fp_reg_count = 8, + .gp_slot_size = 8, + .fp_slot_size = 16}, }; diff --git a/src/abi/abi_internal.h b/src/abi/abi_internal.h @@ -14,6 +14,7 @@ typedef struct ABIVtable { * abi.c calls this once per CgTypeId and memoizes the result. */ ABIFuncInfo* (*compute_func_info)(TargetABI*, CfreeCgTypeId fn); ABITypeInfo va_list_info; + ABIVaListInfo va_list_layout; } ABIVtable; /* Per-ABI vtables exposed by their TUs. */ diff --git a/src/abi/abi_rv64.c b/src/abi/abi_rv64.c @@ -246,4 +246,6 @@ static ABIFuncInfo* rv64_compute_func_info(TargetABI* a, CfreeCgTypeId fn) { const ABIVtable rv64_vtable = { .compute_func_info = rv64_compute_func_info, .va_list_info = {8, 8, ABI_SC_PTR, 0, 0, 0}, + .va_list_layout = + {.type = {8, 8, ABI_SC_PTR, 0, 0, 0}, .kind = ABI_VA_LIST_POINTER}, }; diff --git a/src/abi/abi_sysv_x64.c b/src/abi/abi_sysv_x64.c @@ -296,4 +296,15 @@ static ABIFuncInfo* sysv_x64_compute_func_info(TargetABI* a, CfreeCgTypeId fn) { const ABIVtable sysv_x64_vtable = { .compute_func_info = sysv_x64_compute_func_info, .va_list_info = {24, 8, ABI_SC_VOID, 0, 0, 0}, + .va_list_layout = + {.type = {24, 8, ABI_SC_VOID, 0, 0, 0}, + .kind = ABI_VA_LIST_SYSV_X64, + .stack_offset = 8, + .gr_top_offset = 16, + .gr_offs_offset = 0, + .vr_offs_offset = 4, + .gp_reg_count = SYSV_X64_GP_REG_COUNT, + .fp_reg_count = SYSV_X64_FP_REG_COUNT, + .gp_slot_size = SYSV_X64_GP_SLOT_SIZE, + .fp_slot_size = SYSV_X64_FP_SLOT_SIZE}, }; diff --git a/src/abi/abi_win64_x64.c b/src/abi/abi_win64_x64.c @@ -175,4 +175,6 @@ static ABIFuncInfo* win64_x64_compute_func_info(TargetABI* a, const ABIVtable win64_x64_vtable = { .compute_func_info = win64_x64_compute_func_info, .va_list_info = {8, 8, ABI_SC_PTR, 0, 0, 0}, + .va_list_layout = + {.type = {8, 8, ABI_SC_PTR, 0, 0, 0}, .kind = ABI_VA_LIST_POINTER}, };