c_abi.c (6563B)
1 #include "abi/c_abi.h" 2 3 #include <string.h> 4 5 ABITypeInfo c_abi_type_info(KitCompiler* a, const Type* t) { 6 KitCgTypeId id = type_cg_id(a, t); 7 KitCgTypeKind kind = kit_cg_type_kind(a, id); 8 ABITypeInfo r; 9 memset(&r, 0, sizeof(r)); 10 r.size = (u32)kit_cg_type_size(a, id); 11 r.align = kit_cg_type_align(a, id); 12 switch (kind) { 13 case KIT_CG_TYPE_VOID: 14 r.scalar_kind = ABI_SC_VOID; 15 break; 16 case KIT_CG_TYPE_BOOL: 17 r.scalar_kind = ABI_SC_BOOL; 18 break; 19 case KIT_CG_TYPE_INT: 20 case KIT_CG_TYPE_ENUM: 21 r.scalar_kind = ABI_SC_INT; 22 break; 23 case KIT_CG_TYPE_FLOAT: 24 r.scalar_kind = ABI_SC_FLOAT; 25 break; 26 case KIT_CG_TYPE_PTR: 27 r.scalar_kind = ABI_SC_PTR; 28 break; 29 default: 30 r.scalar_kind = ABI_SC_VOID; 31 break; 32 } 33 r.signed_ = type_is_signed_integer(t); 34 return r; 35 } 36 37 u32 c_abi_sizeof(KitCompiler* a, const Type* t) { 38 return c_abi_type_info(a, t).size; 39 } 40 41 u32 c_abi_alignof(KitCompiler* a, const Type* t) { 42 return c_abi_type_info(a, t).align; 43 } 44 45 const ABIRecordLayout* c_abi_record_layout(KitCompiler* a, Pool* p, 46 const Type* t) { 47 KitCgTypeId id = type_cg_id_in_pool(a, p, t); 48 ABIRecordLayout* L; 49 ABIFieldLayout* fl = NULL; 50 u32 nfields; 51 if (kit_cg_type_kind(a, id) != KIT_CG_TYPE_RECORD) return NULL; 52 nfields = kit_cg_type_record_nfields(a, id); 53 L = arena_znew(p->arena, ABIRecordLayout); 54 if (!L) return NULL; 55 if (nfields) { 56 fl = arena_zarray(p->arena, ABIFieldLayout, nfields); 57 if (!fl) return NULL; 58 for (u32 i = 0; i < nfields; ++i) { 59 KitCgField f; 60 uint64_t off = 0; 61 memset(&f, 0, sizeof(f)); 62 if (kit_cg_type_record_field(a, id, i, &f, &off) != 0) return NULL; 63 fl[i].offset = (u32)off; 64 fl[i].storage_size = f.bit_storage_size 65 ? f.bit_storage_size 66 : (u32)kit_cg_type_size(a, f.type); 67 if (t->rec.fields[i].flags & FIELD_BITFIELD) { 68 fl[i].bit_width = t->rec.fields[i].bitfield_width; 69 fl[i].bit_offset = f.bit_offset; 70 } 71 } 72 } 73 L->size = (u32)kit_cg_type_size(a, id); 74 L->align = kit_cg_type_align(a, id); 75 L->nfields = nfields; 76 L->fields = fl; 77 return L; 78 } 79 80 const ABIFuncInfo* c_abi_func_info(KitCompiler* a, Pool* p, 81 const Type* fn_type) { 82 KitCgTypeId id = type_cg_id_in_pool(a, p, fn_type); 83 ABIFuncInfo* info; 84 uint32_t nparams; 85 if (kit_cg_type_kind(a, id) != KIT_CG_TYPE_FUNC) return NULL; 86 nparams = kit_cg_type_func_nparams(a, id); 87 info = arena_znew(p->arena, ABIFuncInfo); 88 if (!info) return NULL; 89 info->nparams = (u16)nparams; 90 if (nparams) { 91 info->params = arena_zarray(p->arena, ABIArgInfo, nparams); 92 if (!info->params) return NULL; 93 } 94 return info; 95 } 96 97 static const Type* c_size_or_uintptr(KitCompiler* a, Pool* p) { 98 KitTargetSpec target = kit_compiler_target_spec(a); 99 if (kit_target_uses_lp64(target)) return type_prim(p, TY_ULONG); 100 return target.ptr_size == 8 ? type_prim(p, TY_ULLONG) : type_prim(p, TY_UINT); 101 } 102 103 const Type* c_abi_size_type(KitCompiler* a, Pool* p) { 104 return c_size_or_uintptr(a, p); 105 } 106 107 const Type* c_abi_ptrdiff_type(KitCompiler* a, Pool* p) { 108 KitTargetSpec target = kit_compiler_target_spec(a); 109 if (kit_target_uses_lp64(target)) return type_prim(p, TY_LONG); 110 return target.ptr_size == 8 ? type_prim(p, TY_LLONG) : type_prim(p, TY_INT); 111 } 112 113 const Type* c_abi_intptr_type(KitCompiler* a, Pool* p) { 114 return c_abi_ptrdiff_type(a, p); 115 } 116 117 const Type* c_abi_uintptr_type(KitCompiler* a, Pool* p) { 118 return c_size_or_uintptr(a, p); 119 } 120 121 const Type* c_abi_va_list_type(KitCompiler* a, Pool* p) { 122 /* Key the frontend `__builtin_va_list` spelling on the abstract va_list 123 * shape the target ABI reports, not on a re-derived arch/os ladder. The 124 * record field definitions are unchanged; only the dispatch is abstract: 125 * SYSV_X64 -> the System V __va_list_tag register-save record; 126 * AAPCS64 -> the AArch64 __va_list register-save record; 127 * POINTER / OPAQUE -> a single pointer that walks the arg area. 128 * The old Apple-vs-AAPCS64 arm64 split disappears (Apple is POINTER), as 129 * does the x86_64/rv64 split (both follow the abstract kind). */ 130 switch (kit_cg_target_va_list_kind(a)) { 131 case KIT_CG_VALIST_SYSV_X64: { 132 const Type* vp = type_ptr(p, type_void(p)); 133 const Type* uit = type_prim(p, TY_UINT); 134 Sym name = kit_sym_intern(p->c, KIT_SLICE_LIT("__va_list_tag")); 135 SrcLoc nl = {0, 0, 0}; 136 TagId tg = type_tag_new(p, TAG_STRUCT, name, nl); 137 TypeRecordBuilder* b = type_record_begin(p, TY_STRUCT, tg, name); 138 type_record_field( 139 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("gp_offset")), 140 .type = uit}); 141 type_record_field( 142 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("fp_offset")), 143 .type = uit}); 144 type_record_field( 145 b, (Field){.name = kit_sym_intern(p->c, 146 KIT_SLICE_LIT("overflow_arg_area")), 147 .type = vp}); 148 type_record_field(b, (Field){.name = kit_sym_intern( 149 p->c, KIT_SLICE_LIT("reg_save_area")), 150 .type = vp}); 151 return type_record_end(p, b); 152 } 153 case KIT_CG_VALIST_AAPCS64: { 154 const Type* vp = type_ptr(p, type_void(p)); 155 const Type* it = type_prim(p, TY_INT); 156 Sym name = kit_sym_intern(p->c, KIT_SLICE_LIT("__va_list")); 157 SrcLoc nl = {0, 0, 0}; 158 TagId tg = type_tag_new(p, TAG_STRUCT, name, nl); 159 TypeRecordBuilder* b = type_record_begin(p, TY_STRUCT, tg, name); 160 type_record_field( 161 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("__stack")), 162 .type = vp}); 163 type_record_field( 164 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("__gr_top")), 165 .type = vp}); 166 type_record_field( 167 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("__vr_top")), 168 .type = vp}); 169 type_record_field( 170 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("__gr_offs")), 171 .type = it}); 172 type_record_field( 173 b, (Field){.name = kit_sym_intern(p->c, KIT_SLICE_LIT("__vr_offs")), 174 .type = it}); 175 return type_record_end(p, b); 176 } 177 case KIT_CG_VALIST_POINTER: 178 case KIT_CG_VALIST_OPAQUE: 179 break; 180 } 181 return type_ptr(p, type_void(p)); 182 }