type.h (6025B)
1 #ifndef KIT_CG_TYPE_H 2 #define KIT_CG_TYPE_H 3 4 #include <kit/cg.h> 5 6 #include "abi/abi.h" 7 #include "core/core.h" 8 9 typedef struct CgTypeField { 10 KitSym name; 11 KitCgTypeId type; 12 u64 offset; 13 u32 align_override; 14 u32 max_align; 15 u32 flags; 16 u16 bit_width; 17 u16 bit_offset; 18 u32 bit_storage_size; 19 int bit_signed; 20 } CgTypeField; 21 22 typedef struct CgType { 23 KitCgTypeKind kind; 24 u64 size; 25 u32 align; 26 u32 pad; 27 union { 28 struct { 29 u32 width; 30 } integer; 31 struct { 32 u32 width; 33 } fp; 34 struct { 35 KitCgTypeId pointee; 36 u32 address_space; 37 } ptr; 38 struct { 39 KitCgTypeId elem; 40 u64 count; 41 } array; 42 struct { 43 KitCgFuncResult result; /* void builtin means no value */ 44 const KitCgFuncParam* params; 45 u32 nparams; 46 KitCgCallConv call_conv; 47 int abi_variadic; 48 } func; 49 struct { 50 KitSym tag; 51 CgTypeField* fields; 52 u32 nfields; 53 int is_union; 54 u32 align_override; 55 u32 flags; 56 /* Lazily-built, CG-owned record-layout view returned by 57 * kit_cg_type_record_layout. NULL until first request; allocated from the 58 * compiler arena so the pointer is stable for the compiler's lifetime. */ 59 KitCgRecordLayout* layout_view; 60 } record; 61 struct { 62 KitSym tag; 63 KitCgTypeId base; 64 KitCgEnumValue* values; 65 u32 nvalues; 66 } enum_; 67 }; 68 } CgType; 69 70 #define CG_TYPE_RECORD_COMPLETE 0x1u 71 72 const CgType* cg_type_get(Compiler*, KitCgTypeId); 73 uint64_t cg_type_size(Compiler*, KitCgTypeId); 74 uint32_t cg_type_align(Compiler*, KitCgTypeId); 75 int cg_type_is_int(Compiler*, KitCgTypeId); 76 int cg_type_is_float(Compiler*, KitCgTypeId); 77 int cg_type_is_ptr(Compiler*, KitCgTypeId); 78 int cg_type_is_record(Compiler*, KitCgTypeId); 79 80 KitCgTypeId builtin_id(KitCgBuiltinType); 81 KitCgTypeId resolve_type(Compiler*, KitCgTypeId); 82 int cg_type_is_void(Compiler*, KitCgTypeId); 83 int cg_type_is_aggregate(Compiler*, KitCgTypeId); 84 85 /* Flat per-id predicate bitset. The six cg_type_is_* predicates are 86 * (bits & API_PRED_*) tests over this set; a site that asks several predicates 87 * of the SAME id reads the bitset once via api_type_pred_bits and tests the 88 * masks locally (one decode, not N). The membership rules MUST match 89 * cg_type_is_* exactly: INT covers INT|BOOL|ENUM and AGGREGATE == RECORD. */ 90 #define API_PRED_INT 0x01u 91 #define API_PRED_FLOAT 0x02u 92 #define API_PRED_PTR 0x04u 93 #define API_PRED_VOID 0x08u 94 #define API_PRED_RECORD 0x10u 95 #define API_PRED_AGGREGATE 0x20u 96 u8 api_type_pred_bits(Compiler*, KitCgTypeId); 97 98 /* Codegen-relevant scalar predicates: a value of this type is a float, a 99 * 128-bit scalar (f128 / i128), or a wide 8-byte scalar the selected ABI splits 100 * into two 32-bit lanes (forced memory-resident; legalized as lane sequences / 101 * runtime calls). Pure functions of (type, target ABI). */ 102 int api_type_is_float(Compiler*, KitCgTypeId); 103 int api_is_f128_type(Compiler*, KitCgTypeId); 104 int api_is_i128_type(Compiler*, KitCgTypeId); 105 int api_is_wide16_scalar_type(Compiler*, KitCgTypeId); /* f128 || i128 */ 106 int api_is_wide8_scalar_type(Compiler*, KitCgTypeId); 107 108 /* The wide / soft-float dispatch class of a scalar type — mutually exclusive, 109 * cached once per value on the value-stack node so the per-operand wide/soft 110 * predicates become a one-byte compare instead of a fresh type-query gauntlet. 111 * Pure function of the type and the target's fixed float-ABI / split-lane 112 * policy. WK_NARROW == 0 is the common fast path. */ 113 typedef enum ApiWideKind { 114 WK_NARROW = 0, /* not wide / not soft-float: the common fast path */ 115 WK_I128, /* 128-bit integer (api_is_i128_type) */ 116 WK_F128, /* 128-bit float / long double (api_is_f128_type) */ 117 WK_WIDE8, /* int split into two 32-bit lanes (api_is_wide8_scalar_type) */ 118 WK_SOFT_DOUBLE, /* f64 on a target without hardware double */ 119 WK_SOFT_SINGLE, /* f32 on a pure-soft target (no FP unit) */ 120 } ApiWideKind; 121 122 /* api_type_class packs a type's codegen classification into one byte: the 123 * ApiWideKind in the low bits plus an aggregate-place bit. Both are pure 124 * functions of (type, target), so the result is memoized per type id (builtins 125 * precomputed at cg_api init, user types lazily) rather than re-derived on 126 * every value push. */ 127 #define API_TYPE_CLASS_WIDE_MASK 0x07u 128 #define API_TYPE_CLASS_AGGREGATE 0x08u 129 u8 api_type_class(Compiler*, KitCgTypeId); 130 131 /* Per-type-id memo for the ABI layout triple (size/align/scalar_kind + the 132 * signed/atomic riders). abi_cg_type_info recurses through alias/enum/array 133 * chains and is hit several times per statement; caching the resolved result 134 * on the type entry collapses each repeat (and the alias chase) to one load. 135 * Types are immutable once built, so the cache never needs invalidation. 136 * _ref returns a borrowed pointer to the cached ABITypeInfo (no field-by-field 137 * copy) or NULL on a miss; the pointer is stable for the compiler's life. 138 * Builtins resolve against a precomputed per-compiler table in CgApiState (also 139 * mirrored on Compiler.cg_builtin_layout for the inline fast path in 140 * abi_cg_type_info), so they hit this memo path without creating CgApiType 141 * entries. */ 142 const ABITypeInfo* api_type_layout_ref(Compiler*, KitCgTypeId); 143 void api_type_layout_put(Compiler*, KitCgTypeId, ABITypeInfo); 144 145 KitCgTypeId cg_type_ptr_to(Compiler*, KitCgTypeId); 146 KitCgTypeId cg_type_pointee(Compiler*, KitCgTypeId); 147 /* The function's result type. A no-value return is the VOID builtin. */ 148 KitCgTypeId cg_type_func_ret_id(Compiler*, KitCgTypeId); 149 /* Same as cg_type_func_ret_id, kept for callers that distinguish the 150 * single-result path from the full KitCgFuncResult descriptor. */ 151 KitCgTypeId cg_type_func_result_id(Compiler*, KitCgTypeId); 152 /* First-result type given a resolved KIT_CG_TYPE_FUNC CgType. For 153 * the single-result/void consumers (ABI classification, source backends) that 154 * already hold the CgType. */ 155 KitCgTypeId cg_func_ret_type(const CgType* fnty); 156 KitCgTypeId cg_type_func_param_id(Compiler*, KitCgTypeId, uint32_t); 157 158 #endif