kit

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

cg.h (76535B)


      1 #ifndef KIT_PUBLIC_CG_H
      2 #define KIT_PUBLIC_CG_H
      3 
      4 #include <kit/core.h>
      5 #include <kit/object.h>
      6 #include <kit/asm_constraints.h>
      7 
      8 /* ============================================================
      9  * Handles
     10  * ============================================================ */
     11 
     12 typedef struct KitCg KitCg;
     13 
     14 typedef uint32_t KitCgLabel;
     15 typedef uint32_t KitCgLocal;
     16 typedef uint32_t KitCgScope;
     17 typedef uint32_t KitCgSym;
     18 typedef uint32_t KitCgTypeId;
     19 typedef uint32_t KitCgDebugType;
     20 
     21 #define KIT_CG_LABEL_NONE 0u
     22 #define KIT_CG_LOCAL_NONE 0u
     23 #define KIT_CG_SCOPE_NONE 0u
     24 #define KIT_CG_SYM_NONE 0u
     25 /* Invalid or absent type sentinel. Void is represented by the real void
     26  * builtin type id, never by KIT_CG_TYPE_NONE. */
     27 #define KIT_CG_TYPE_NONE 0u
     28 /* Optional debug type sentinel. Declaration sites that pass NONE derive a
     29  * default debug type from the operational KitCgTypeId. */
     30 #define KIT_CG_DEBUG_TYPE_NONE 0u
     31 
     32 /* ============================================================
     33  * Lifecycle and Source Locations
     34  * ============================================================ */
     35 
     36 KIT_API KitStatus kit_cg_new(KitCompiler*, KitCg** cg_out);
     37 
     38 typedef struct KitCgUnitOptions {
     39   KitSlice source_name; /* diagnostic/provenance label; may be empty */
     40   uint32_t source_id;   /* 0 means "unspecified" */
     41   uint32_t flags;       /* reserved; must be 0 */
     42 } KitCgUnitOptions;
     43 
     44 typedef enum KitCgOutputKind {
     45   KIT_CG_OUTPUT_RELOCATABLE = 0,
     46   KIT_CG_OUTPUT_EXECUTABLE = 1,
     47   KIT_CG_OUTPUT_SHARED = 2,
     48   KIT_CG_OUTPUT_ARCHIVE_MEMBER = 3,
     49 } KitCgOutputKind;
     50 
     51 typedef enum KitCgInterpositionPolicy {
     52   KIT_CG_INTERPOSITION_DEFAULT = 0,
     53   KIT_CG_INTERPOSITION_NONE = 1,
     54   KIT_CG_INTERPOSITION_DEFAULT_VISIBILITY = 2,
     55 } KitCgInterpositionPolicy;
     56 
     57 typedef struct KitCgFinishOptions {
     58   uint8_t output_kind;          /* KitCgOutputKind */
     59   uint8_t interposition_policy; /* KitCgInterpositionPolicy */
     60   uint8_t pad[2];
     61   const KitCgSym* preserved_symbols;
     62   uint32_t npreserved_symbols;
     63 } KitCgFinishOptions;
     64 
     65 KIT_API KitStatus kit_cg_begin(KitCg*, KitObjBuilder* out,
     66                                const KitCodeOptions*);
     67 KIT_API KitStatus kit_cg_begin_unit(KitCg*, const KitCgUnitOptions*);
     68 KIT_API KitStatus kit_cg_end_unit(KitCg*);
     69 KIT_API KitStatus kit_cg_finish(KitCg*, const KitCgFinishOptions*);
     70 /* Release the session, abandoning any in-progress object/unit state. Used on
     71  * both the success-detach and error-abort paths. */
     72 KIT_API KitStatus kit_cg_detach(KitCg*);
     73 KIT_API void kit_cg_free(KitCg*);
     74 
     75 /* Sticky source location. Function, scope, local, param, instruction, and
     76  * data-definition debug records use the current location. */
     77 KIT_API void kit_cg_set_loc(KitCg*, KitSrcLoc);
     78 
     79 /* ============================================================
     80  * ABI Descriptors
     81  * ============================================================ */
     82 
     83 /* Source-selectable calling convention: the convention axis a frontend can vary
     84  * *within one compilation*, not the target's ABI identity (that is fixed by the
     85  * triple). KIT_CG_CC_TARGET_C selects the target's own C ABI — whichever of
     86  * SysV / Win64 / AAPCS64 / wasm the triple implies — and is the only convention
     87  * kit lowers today. A real variant that repartitions the call (e.g. an x86
     88  * vectorcall/regparm, preserve_most) would be added here and gated by
     89  * kit_cg_target_supports_call_conv. Definition-side conventions that change the
     90  * prologue but not the call ABI (naked, interrupt) are function attributes —
     91  * KIT_CG_FUNC_NAKED / KIT_CG_FUNC_INTERRUPT — not values here. */
     92 typedef enum KitCgCallConv {
     93   KIT_CG_CC_TARGET_C,
     94 } KitCgCallConv;
     95 
     96 typedef enum KitCgAbiAttrFlag {
     97   KIT_CG_ABI_NONE = 0,
     98   KIT_CG_ABI_SIGNEXT = 1u << 0,
     99   KIT_CG_ABI_ZEROEXT = 1u << 1,
    100   KIT_CG_ABI_SRET = 1u << 2,
    101   KIT_CG_ABI_BYVAL = 1u << 3,
    102   KIT_CG_ABI_BYREF = 1u << 4,
    103   KIT_CG_ABI_INREG = 1u << 5,
    104   KIT_CG_ABI_NOALIAS = 1u << 6,
    105   KIT_CG_ABI_READONLY = 1u << 7,
    106   KIT_CG_ABI_WRITEONLY = 1u << 8,
    107   KIT_CG_ABI_NONNULL = 1u << 9,
    108   KIT_CG_ABI_NEST = 1u << 10,
    109 } KitCgAbiAttrFlag;
    110 
    111 typedef struct KitCgAbiAttrs {
    112   uint32_t flags; /* KitCgAbiAttrFlag */
    113   uint32_t align; /* 0 = ABI default */
    114   uint64_t dereferenceable_size;
    115 } KitCgAbiAttrs;
    116 
    117 typedef struct KitCgFuncParam {
    118   KitCgTypeId type;
    119   KitCgAbiAttrs attrs;
    120 } KitCgFuncParam;
    121 
    122 /* A function result is described exactly like a parameter: a type plus ABI
    123  * attrs. The legal attribute subsets differ (SRET on results; BYVAL/NEST on
    124  * params), but the descriptor shape is identical, so KitCgFuncResult is an
    125  * alias of KitCgFuncParam. result.type is always a valid type id; use
    126  * kit_cg_type_builtin(c, KIT_CG_BUILTIN_VOID) for a function that returns no
    127  * value. */
    128 typedef KitCgFuncParam KitCgFuncResult;
    129 
    130 typedef struct KitCgFuncSig {
    131   KitCgFuncResult result; /* void builtin means no value */
    132   const KitCgFuncParam* params;
    133   uint32_t nparams;
    134   KitCgCallConv call_conv;
    135   bool abi_variadic;
    136 } KitCgFuncSig;
    137 
    138 /* Capability queries answer whether the selected target/API can lower the
    139  * requested feature correctly, not whether it is fast. These are target
    140  * facts, not knobs: frontends use them to choose a legal lowering or to emit
    141  * an unsupported-feature diagnostic before asking CG to produce output. */
    142 KIT_API int kit_cg_target_supports_call_conv(KitCompiler*, KitCgCallConv);
    143 
    144 /* ============================================================
    145  * Type System
    146  * ============================================================ */
    147 
    148 typedef enum KitCgBuiltinType {
    149   KIT_CG_BUILTIN_VOID,
    150   KIT_CG_BUILTIN_BOOL, /* i1: compare result and branch condition */
    151   KIT_CG_BUILTIN_I8,
    152   KIT_CG_BUILTIN_I16,
    153   KIT_CG_BUILTIN_I32,
    154   KIT_CG_BUILTIN_I64,
    155   KIT_CG_BUILTIN_I128,
    156   KIT_CG_BUILTIN_F32,
    157   KIT_CG_BUILTIN_F64,
    158   KIT_CG_BUILTIN_F128,
    159   KIT_CG_BUILTIN_VARARG_STATE,
    160   KIT_CG_BUILTIN_COUNT,
    161 } KitCgBuiltinType;
    162 
    163 typedef enum KitCgTypeKind {
    164   KIT_CG_TYPE_VOID,
    165   KIT_CG_TYPE_BOOL,
    166   KIT_CG_TYPE_INT,
    167   KIT_CG_TYPE_FLOAT,
    168   KIT_CG_TYPE_PTR,
    169   KIT_CG_TYPE_ARRAY,
    170   KIT_CG_TYPE_FUNC,
    171   KIT_CG_TYPE_RECORD,
    172   KIT_CG_TYPE_ENUM,
    173   KIT_CG_TYPE_VARARG_STATE,
    174 } KitCgTypeKind;
    175 
    176 /* Field descriptor for record completion (INPUT). Carries the field's source
    177  * shape and layout *policy* — alignment knobs and bit-field width — never its
    178  * position: CG computes byte/bit offsets from these and the target ABI. Query
    179  * the results back with kit_cg_type_record_layout after completion. */
    180 typedef struct KitCgFieldDesc {
    181   KitSym name; /* 0 for anonymous fields/tuple elements */
    182   KitCgTypeId type;
    183   uint32_t align_override; /* 0 = natural, 1 = packed, >1 explicit align */
    184   uint32_t max_align;      /* 0 = natural, otherwise cap field alignment */
    185   uint32_t flags;          /* KitCgFieldFlag */
    186   uint16_t bit_width;      /* bit-field width; 0 w/ BITFIELD = layout barrier */
    187   int bit_signed;          /* signed extraction for bit-field loads */
    188 } KitCgFieldDesc;
    189 
    190 typedef enum KitCgFieldFlag {
    191   KIT_CG_FIELD_BITFIELD = 1u << 0,
    192 } KitCgFieldFlag;
    193 
    194 /* Computed layout of one record field (OUTPUT; borrowed via the record-layout
    195  * view, never an input to completion). For a bit-field, `offset` is the byte
    196  * offset of the storage unit and the bit_* members carry the geometry; for an
    197  * ordinary field bit_width == 0 and the bit_* members are 0. */
    198 typedef struct KitCgFieldLayout {
    199   KitSym name;
    200   KitCgTypeId type;
    201   uint64_t offset; /* byte offset of the field (or its storage unit) */
    202   uint32_t flags;  /* KitCgFieldFlag */
    203   uint32_t bit_storage_size; /* storage-unit bytes for a bit-field, else 0 */
    204   uint16_t bit_offset;       /* bit position within the storage unit */
    205   uint16_t bit_width;        /* 0 for a non-bit-field */
    206   int bit_signed;            /* signed extraction for bit-field loads */
    207 } KitCgFieldLayout;
    208 
    209 /* Immutable, CG-owned record layout, borrowed via kit_cg_type_record_layout.
    210  * The pointer and its fields array stay valid and unchanged for the compiler's
    211  * lifetime once the record is complete, so frontends cache this pointer instead
    212  * of copying offsets into a parallel layout table. */
    213 typedef struct KitCgRecordLayout {
    214   uint64_t size;
    215   uint32_t align;
    216   uint32_t nfields;
    217   const KitCgFieldLayout* fields;
    218 } KitCgRecordLayout;
    219 
    220 typedef struct KitCgEnumValue {
    221   KitSym name;
    222   uint64_t value; /* bit pattern interpreted using the enum's integer base */
    223 } KitCgEnumValue;
    224 
    225 typedef struct KitCgRecordDesc {
    226   KitSym tag;
    227   const KitCgFieldDesc* fields;
    228   uint32_t nfields;
    229   int is_union;
    230   uint32_t align_override; /* 0 = natural, >0 explicit record alignment */
    231 } KitCgRecordDesc;
    232 
    233 typedef enum KitCgTypeFlag {
    234   KIT_CG_TYPEF_COMPLETE = 1u << 0,
    235   KIT_CG_TYPEF_SIZED = 1u << 1,
    236   KIT_CG_TYPEF_BUILTIN = 1u << 2,
    237   KIT_CG_TYPEF_NOMINAL = 1u << 3,
    238 } KitCgTypeFlag;
    239 
    240 typedef enum KitCgStorageKind {
    241   KIT_CG_STORAGE_VOID,
    242   KIT_CG_STORAGE_BOOL,
    243   KIT_CG_STORAGE_INT,
    244   KIT_CG_STORAGE_FLOAT,
    245   KIT_CG_STORAGE_PTR,
    246   KIT_CG_STORAGE_AGGREGATE,
    247 } KitCgStorageKind;
    248 
    249 typedef struct KitCgTypeLayout {
    250   uint64_t size;
    251   uint32_t align;
    252   uint16_t scalar_width; /* bit width for scalar int/float/bool, else 0 */
    253   uint8_t storage_kind;  /* KitCgStorageKind */
    254   uint8_t valid;         /* 0 for invalid, incomplete, or unsized types */
    255 } KitCgTypeLayout;
    256 
    257 typedef struct KitCgTypeInfo {
    258   KitCgTypeId id;
    259   KitCgTypeId storage_id; /* storage identity; always equal to id */
    260   KitCgTypeKind kind;     /* exact kind */
    261   uint32_t flags;         /* KitCgTypeFlag */
    262   KitCgTypeLayout layout; /* ABI/storage layout; valid only when sized */
    263 } KitCgTypeInfo;
    264 
    265 /* Type ids are stable only within one compiler. Pointer, array, and function
    266  * constructors return a stable id for the same exact shape within one compiler;
    267  * aliases, records, and enums allocate fresh user-facing identities. Void is a
    268  * builtin type id; KIT_CG_TYPE_NONE is invalid/absent only.
    269  *
    270  * Integer types are width-only storage types. Signedness is carried by
    271  * operations, comparisons, conversions, and ABI extension attributes. */
    272 KIT_API KitCgTypeId kit_cg_type_builtin(KitCompiler*, KitCgBuiltinType which);
    273 
    274 /* Interned structural types. Address space 0 is the normal target data
    275  * address space. Function signatures must use the void builtin type id as the
    276  * result type for a no-value return. */
    277 KIT_API KitCgTypeId kit_cg_type_func(KitCompiler*, KitCgFuncSig sig);
    278 KIT_API KitCgTypeId kit_cg_type_ptr(KitCompiler*, KitCgTypeId pointee,
    279                                     uint32_t address_space);
    280 KIT_API KitCgTypeId kit_cg_type_array(KitCompiler*, KitCgTypeId elem,
    281                                       uint64_t count);
    282 
    283 /* Enums use a width-only integer base. */
    284 KIT_API KitCgTypeId kit_cg_type_enum(KitCompiler*, KitSym tag, KitCgTypeId base,
    285                                      const KitCgEnumValue* values,
    286                                      uint32_t nvalues);
    287 
    288 /* Records are nominal and may be declared before they are complete. Pointers
    289  * to incomplete records are valid; sizing, arrays, fields, by-value
    290  * params/results, locals, and memory accesses require complete/sized types.
    291  * Completion is one-shot and computes ABI/source layout for the record. */
    292 KIT_API KitCgTypeId kit_cg_type_record_decl(KitCompiler*, KitSym tag,
    293                                             int is_union);
    294 KIT_API KitStatus kit_cg_type_record_complete(KitCompiler*, KitCgTypeId record,
    295                                               const KitCgRecordDesc*);
    296 /* Convenience constructor: declare a fresh nominal record, complete it, and
    297  * return its id, or KIT_CG_TYPE_NONE on failure. */
    298 static inline KitCgTypeId kit_cg_type_record(KitCompiler* c,
    299                                              const KitCgRecordDesc* desc) {
    300   KitCgTypeId record;
    301   if (!desc) return KIT_CG_TYPE_NONE;
    302   record = kit_cg_type_record_decl(c, desc->tag, desc->is_union);
    303   if (record == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE;
    304   if (kit_cg_type_record_complete(c, record, desc) != KIT_OK)
    305     return KIT_CG_TYPE_NONE;
    306   return record;
    307 }
    308 
    309 /* Type queries.
    310  *
    311  * Layout and width queries report ABI/storage facts. Shape-specific queries are
    312  * exact over the operational type lattice. */
    313 KIT_API KitStatus kit_cg_type_info(KitCompiler*, KitCgTypeId, KitCgTypeInfo*);
    314 
    315 /* Stable per-id identity view. Returns a pointer to an interned KitCgTypeInfo
    316  * whose IDENTITY fields are authoritative for the lifetime of the compiler:
    317  * id, storage_id (always id), kind, and the BUILTIN / NOMINAL flag bits. The
    318  * layout substruct and the COMPLETE / SIZED flag bits are NOT maintained on
    319  * this view — completeness and sizing can change as records complete, and
    320  * layout is computed lazily — so call kit_cg_type_info for an authoritative
    321  * full snapshot. Returns NULL for an invalid id. The cheap identity queries
    322  * below are inline projections over this one extern. */
    323 KIT_API const KitCgTypeInfo* kit_cg_type_view(KitCompiler*, KitCgTypeId);
    324 
    325 KIT_API int kit_cg_type_same_storage(KitCompiler*, KitCgTypeId, KitCgTypeId);
    326 KIT_API int kit_cg_type_is_complete(KitCompiler*, KitCgTypeId);
    327 KIT_API int kit_cg_type_is_sized(KitCompiler*, KitCgTypeId);
    328 
    329 static inline KitCgTypeKind kit_cg_type_kind(KitCompiler* c, KitCgTypeId id) {
    330   const KitCgTypeInfo* t = kit_cg_type_view(c, id);
    331   return t ? t->kind : KIT_CG_TYPE_VOID;
    332 }
    333 /* The storage id. With no transparent wrapper kinds, this is identity. */
    334 static inline KitCgTypeId kit_cg_type_resolve_alias(KitCompiler* c,
    335                                                     KitCgTypeId id) {
    336   const KitCgTypeInfo* t = kit_cg_type_view(c, id);
    337   return t ? t->id : KIT_CG_TYPE_NONE;
    338 }
    339 static inline int kit_cg_type_is_void(KitCompiler* c, KitCgTypeId id) {
    340   const KitCgTypeInfo* t = kit_cg_type_view(c, id);
    341   return t && t->kind == KIT_CG_TYPE_VOID;
    342 }
    343 /* A function result carries a value unless it is absent or the void builtin. */
    344 static inline int kit_cg_func_result_has_value(KitCompiler* c,
    345                                                KitCgFuncResult result) {
    346   return result.type != KIT_CG_TYPE_NONE &&
    347          !kit_cg_type_is_void(c, result.type);
    348 }
    349 KIT_API uint64_t kit_cg_type_size(KitCompiler*, KitCgTypeId);
    350 KIT_API uint32_t kit_cg_type_align(KitCompiler*, KitCgTypeId);
    351 KIT_API uint32_t kit_cg_type_int_width(KitCompiler*, KitCgTypeId);
    352 KIT_API uint32_t kit_cg_type_float_width(KitCompiler*, KitCgTypeId);
    353 
    354 KIT_API KitCgTypeId kit_cg_type_ptr_pointee(KitCompiler*, KitCgTypeId);
    355 KIT_API uint32_t kit_cg_type_ptr_address_space(KitCompiler*, KitCgTypeId);
    356 KIT_API KitCgTypeId kit_cg_type_array_elem(KitCompiler*, KitCgTypeId);
    357 KIT_API uint64_t kit_cg_type_array_count(KitCompiler*, KitCgTypeId);
    358 
    359 /* The function's result. A no-value result uses the void builtin type id. */
    360 KIT_API KitCgFuncResult kit_cg_type_func_result(KitCompiler*, KitCgTypeId);
    361 KIT_API uint32_t kit_cg_type_func_nparams(KitCompiler*, KitCgTypeId);
    362 KIT_API KitCgFuncParam kit_cg_type_func_param(KitCompiler*, KitCgTypeId,
    363                                               uint32_t index);
    364 KIT_API KitCgCallConv kit_cg_type_func_call_conv(KitCompiler*, KitCgTypeId);
    365 KIT_API int kit_cg_type_func_is_variadic(KitCompiler*, KitCgTypeId);
    366 
    367 KIT_API KitSym kit_cg_type_record_tag(KitCompiler*, KitCgTypeId);
    368 KIT_API int kit_cg_type_record_is_union(KitCompiler*, KitCgTypeId);
    369 KIT_API uint32_t kit_cg_type_record_nfields(KitCompiler*, KitCgTypeId);
    370 /* Borrow the computed layout of a complete, sized record: total size/align and
    371  * each field's byte offset and bit geometry. Returns NULL for an invalid id, a
    372  * non-record, or an incomplete/unsized record. The returned pointer is owned by
    373  * CG and stable for the compiler's lifetime; frontends cache it instead of
    374  * copying offsets into a parallel layout table. Replaces per-field record
    375  * queries — fetch once and index fields[] directly. */
    376 KIT_API const KitCgRecordLayout* kit_cg_type_record_layout(KitCompiler*,
    377                                                            KitCgTypeId);
    378 
    379 KIT_API KitSym kit_cg_type_enum_tag(KitCompiler*, KitCgTypeId);
    380 KIT_API KitCgTypeId kit_cg_type_enum_base(KitCompiler*, KitCgTypeId);
    381 KIT_API uint32_t kit_cg_type_enum_nvalues(KitCompiler*, KitCgTypeId);
    382 KIT_API KitStatus kit_cg_type_enum_value(KitCompiler*, KitCgTypeId,
    383                                          uint32_t index, KitCgEnumValue* out);
    384 
    385 /* ============================================================
    386  * Debug Type Information
    387  * ============================================================ */
    388 
    389 /* Debug base-type encoding. Mirrors the producer's DEBUG_BE_* set so frontends
    390  * can round-trip source signedness into debug info without storage carrying it.
    391  */
    392 typedef enum KitCgDebugEncoding {
    393   KIT_CG_DEBUG_ENC_NONE,
    394   KIT_CG_DEBUG_ENC_BOOL,
    395   KIT_CG_DEBUG_ENC_SIGNED,
    396   KIT_CG_DEBUG_ENC_UNSIGNED,
    397   KIT_CG_DEBUG_ENC_SIGNED_CHAR,
    398   KIT_CG_DEBUG_ENC_UNSIGNED_CHAR,
    399   KIT_CG_DEBUG_ENC_FLOAT,
    400 } KitCgDebugEncoding;
    401 
    402 /* Debug type builders. These return KIT_CG_DEBUG_TYPE_NONE when debug emission
    403  * is not active on the KitCg session. The resulting handles are owned by that
    404  * session and are valid only for declaration attributes passed to the same
    405  * session. */
    406 KIT_API KitCgDebugType kit_cg_debug_base(KitCg*, KitSym name,
    407                                          KitCgDebugEncoding, uint32_t bytes);
    408 KIT_API KitCgDebugType kit_cg_debug_typedef(KitCg*, KitSym name,
    409                                             KitCgDebugType base);
    410 KIT_API KitCgDebugType kit_cg_debug_ptr(KitCg*, KitCgDebugType pointee);
    411 KIT_API KitCgDebugType kit_cg_debug_array(KitCg*, KitCgDebugType elem,
    412                                           uint64_t count);
    413 KIT_API KitCgDebugType kit_cg_debug_func(KitCg*, KitCgDebugType ret,
    414                                          const KitCgDebugType* params,
    415                                          uint32_t nparams, int variadic);
    416 KIT_API KitCgDebugType kit_cg_debug_enum(KitCg*, KitCgTypeId enum_type,
    417                                          KitCgDebugType base);
    418 KIT_API KitCgDebugType kit_cg_debug_of_type(KitCg*, KitCgTypeId);
    419 
    420 /* ============================================================
    421  * Target Facts
    422  * ============================================================ */
    423 
    424 typedef enum KitCgBackendFeatureFlag {
    425   KIT_CG_BACKEND_UNALIGNED_MEMORY = 1ull << 0,
    426   KIT_CG_BACKEND_STRICT_ALIGNMENT = 1ull << 1,
    427   KIT_CG_BACKEND_RED_ZONE = 1ull << 2,
    428   KIT_CG_BACKEND_SIMD = 1ull << 3,
    429   KIT_CG_BACKEND_POINTER_AUTH = 1ull << 4,
    430   KIT_CG_BACKEND_BRANCH_PROTECTION = 1ull << 5,
    431   /* Instruction and data caches are coherent: freshly written code is
    432    * executable without an explicit cache-flush / instruction-sync sequence.
    433    * Set for x86 (snooping I-cache) and wasm (no hardware cache model). Not set
    434    * for aarch64 / RISC-V, where JITs and self-modifying code must issue an
    435    * explicit __clear_cache (IC/DC maintenance + ISB; fence.i) before running
    436    * newly emitted instructions. */
    437   KIT_CG_BACKEND_ICACHE_COHERENT = 1ull << 6,
    438 } KitCgBackendFeatureFlag;
    439 
    440 KIT_API uint64_t kit_cg_target_backend_features(KitCompiler*);
    441 
    442 /* Shape of the target's `va_list` object, as an ABI fact. Frontends that
    443  * lower <stdarg.h> consult this to pick the right va_list representation
    444  * without reaching into libkit-internal ABI tables:
    445  *   KIT_CG_VALIST_OPAQUE  : implementation-private blob.
    446  *   KIT_CG_VALIST_POINTER : a single pointer that walks the arg area.
    447  *   KIT_CG_VALIST_AAPCS64 : the AArch64 __va_list register-save record.
    448  *   KIT_CG_VALIST_SYSV_X64: the System V x86-64 register-save record. */
    449 typedef enum KitCgVaListKind {
    450   KIT_CG_VALIST_OPAQUE,
    451   KIT_CG_VALIST_POINTER,
    452   KIT_CG_VALIST_AAPCS64,
    453   KIT_CG_VALIST_SYSV_X64,
    454 } KitCgVaListKind;
    455 KIT_API KitCgVaListKind kit_cg_target_va_list_kind(const KitCompiler*);
    456 
    457 /* The C source-level symbol prefix the active object format prepends on
    458  * disk: "_" for Mach-O, "" for ELF / COFF / Wasm. Never NULL. Drives the
    459  * preprocessor's __USER_LABEL_PREFIX__. */
    460 KIT_API const char* kit_cg_target_c_label_prefix(const KitCompiler*);
    461 
    462 /* Pointer width in bytes for an architecture, as a target fact independent of
    463  * any constructed KitTarget. Single source of truth for the byte-aligned
    464  * pointer size, so the object-format detector, the driver triple parser, and
    465  * any internal CG/link code agree on one mapping. Header-only (no KIT_API TU)
    466  * so it links anywhere the public headers reach — including arches that have no
    467  * codegen backend (x86_32 / arm32 / arm64 are still ABI-classifiable here).
    468  * wasm reports 4 (wasm32; wasm64's 8-byte width is carried on the target spec,
    469  * not the arch kind). Returns 0 for an unknown KitArchKind. */
    470 static inline uint8_t kit_arch_ptr_size(KitArchKind arch) {
    471   switch (arch) {
    472     case KIT_ARCH_X86_32:
    473     case KIT_ARCH_ARM_32:
    474     case KIT_ARCH_RV32:
    475     case KIT_ARCH_WASM:
    476       return 4u;
    477     case KIT_ARCH_X86_64:
    478     case KIT_ARCH_ARM_64:
    479     case KIT_ARCH_RV64:
    480       return 8u;
    481   }
    482   return 0u;
    483 }
    484 
    485 /* ============================================================
    486  * Declarations and Symbols
    487  * ============================================================ */
    488 
    489 typedef enum KitCgVisibility {
    490   /* Externally visible, object-format-default visibility. On ELF this maps to
    491    * STV_DEFAULT and remains preemptible when bind/output mode allow it. On
    492    * formats without an equivalent visibility field, this is the normal visible
    493    * symbol state. Local-bind symbols are still local. */
    494   KIT_CG_VIS_DEFAULT,
    495   KIT_CG_VIS_HIDDEN,
    496   KIT_CG_VIS_PROTECTED,
    497 } KitCgVisibility;
    498 
    499 typedef enum KitCgSymbolFlag {
    500   KIT_CG_SYMFLAG_NONE = 0,
    501   KIT_CG_SYM_USED = 1u << 0,
    502   KIT_CG_SYM_DLLIMPORT = 1u << 1,
    503   KIT_CG_SYM_DLLEXPORT = 1u << 2,
    504 } KitCgSymbolFlag;
    505 
    506 typedef struct KitCgSymbolAttrs {
    507   KitSymBind bind;
    508   KitCgVisibility visibility;
    509   uint32_t flags; /* KitCgSymbolFlag */
    510 } KitCgSymbolAttrs;
    511 
    512 typedef enum KitCgSymbolFeature {
    513   KIT_CG_SYMFEAT_WEAK,
    514   KIT_CG_SYMFEAT_PROTECTED_VISIBILITY,
    515   KIT_CG_SYMFEAT_DLLIMPORT,
    516   KIT_CG_SYMFEAT_DLLEXPORT,
    517   KIT_CG_SYMFEAT_COMDAT,
    518   KIT_CG_SYMFEAT_COMMON,
    519   KIT_CG_SYMFEAT_MERGE_SECTIONS,
    520   KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY,
    521   KIT_CG_SYMFEAT_TLS_LOCAL_EXEC,
    522   KIT_CG_SYMFEAT_TLS_INITIAL_EXEC,
    523   KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC,
    524   KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC,
    525 } KitCgSymbolFeature;
    526 
    527 /* Whether the selected target supports a symbol feature; see
    528  * kit_cg_target_supports_call_conv for the capability-query contract. */
    529 KIT_API int kit_cg_target_supports_symbol_feature(KitCompiler*,
    530                                                   KitCgSymbolFeature);
    531 
    532 typedef enum KitCgFuncFlag {
    533   KIT_CG_FUNC_NONE = 0,
    534   KIT_CG_FUNC_NORETURN = 1u << 0,
    535   KIT_CG_FUNC_IFUNC = 1u << 1,
    536   KIT_CG_FUNC_COLD = 1u << 2,
    537   KIT_CG_FUNC_HOT = 1u << 3,
    538   KIT_CG_FUNC_NAKED = 1u << 4,
    539   KIT_CG_FUNC_INTERRUPT = 1u << 5,
    540   KIT_CG_FUNC_NO_RED_ZONE = 1u << 6,
    541 } KitCgFuncFlag;
    542 
    543 typedef enum KitCgInlinePolicy {
    544   KIT_CG_INLINE_DEFAULT,
    545   KIT_CG_INLINE_HINT,
    546   KIT_CG_INLINE_ALWAYS,
    547   KIT_CG_INLINE_NEVER,
    548 } KitCgInlinePolicy;
    549 
    550 typedef struct KitCgFuncAttrs {
    551   uint32_t flags;       /* KitCgFuncFlag */
    552   uint32_t stack_align; /* 0 = ABI default */
    553   KitSym section;       /* 0 = target default */
    554   KitSym target_features;
    555   KitCgInlinePolicy inline_policy;
    556   KitCgDebugType debug_type; /* 0 = derive from declared function type */
    557   /* Wasm-target import descriptor. Honored only by the wasm backend, ignored
    558    * by other targets. Promotes an undefined function symbol into a wasm
    559    * `(import "<module>" "<name>" ...)` entry instead of a missing definition.
    560    * Both 0 leaves the backend to fall back to module="env", name=<sym name>
    561    * when an undefined function is referenced. */
    562   KitSym wasm_import_module;
    563   KitSym wasm_import_name;
    564 } KitCgFuncAttrs;
    565 
    566 typedef enum KitCgTlsModel {
    567   /* Let the target/backend choose from the symbol properties, visibility,
    568    * output mode, and object format. Non-AUTO values are frontend requests
    569    * from source attributes or driver options; unsupported requests should be
    570    * diagnosed or conservatively widened. Object-format mechanisms such as
    571    * Mach-O TLVP are target-selected implementation details. */
    572   KIT_CG_TLS_AUTO,
    573   KIT_CG_TLS_LOCAL_EXEC,
    574   KIT_CG_TLS_INITIAL_EXEC,
    575   KIT_CG_TLS_LOCAL_DYNAMIC,
    576   KIT_CG_TLS_GENERAL_DYNAMIC,
    577 } KitCgTlsModel;
    578 
    579 typedef enum KitCgObjectFlag {
    580   KIT_CG_OBJ_NONE = 0,
    581   KIT_CG_OBJ_READONLY = 1u << 0,
    582   KIT_CG_OBJ_TLS = 1u << 1,
    583 } KitCgObjectFlag;
    584 
    585 typedef struct KitCgObjectAttrs {
    586   KitCgTlsModel tls_model;
    587   uint32_t flags;            /* KitCgObjectFlag */
    588   KitSym section;            /* 0 = target default */
    589   uint32_t align;            /* 0 = natural */
    590   KitCgDebugType debug_type; /* 0 = derive from object type */
    591 } KitCgObjectAttrs;
    592 
    593 typedef enum KitCgDeclKind {
    594   KIT_CG_DECL_FUNC,
    595   KIT_CG_DECL_OBJECT,
    596 } KitCgDeclKind;
    597 
    598 typedef struct KitCgDecl {
    599   KitCgDeclKind kind;
    600   KitSym linkage_name; /* exact linker-visible spelling */
    601   KitSym display_name; /* optional source/debug spelling; 0 = linkage_name */
    602   KitCgTypeId type;
    603   KitCgSymbolAttrs sym;
    604   union {
    605     KitCgFuncAttrs func;
    606     KitCgObjectAttrs object;
    607   } as;
    608 } KitCgDecl;
    609 
    610 typedef struct KitCgAlias {
    611   KitSym linkage_name;
    612   KitSym display_name; /* optional source/debug spelling; 0 = linkage_name */
    613   KitCgSym target;
    614   KitCgSymbolAttrs sym;
    615 } KitCgAlias;
    616 
    617 /* The declared type is the function type for function declarations and the
    618  * object type for object declarations. linkage_name is already mangled and
    619  * object-format decorated as desired by the frontend; CG does not apply a
    620  * C-language name policy.
    621  *
    622  * Undefined weak references are ordinary declarations with sym.bind =
    623  * KIT_SB_WEAK and no definition. Weak aliases are aliases whose attrs bind
    624  * is KIT_SB_WEAK. */
    625 KIT_API KitCgSym kit_cg_decl(KitCg*, KitCgDecl decl);
    626 
    627 /* Defines alias.linkage_name as another symbol for alias.target. */
    628 KIT_API KitCgSym kit_cg_alias(KitCg*, KitCgAlias alias);
    629 
    630 /* Converts a source-level C ABI symbol spelling to the exact object/linker
    631  * spelling for the selected target. This is object-format decoration only
    632  * (for example Mach-O's leading underscore); language-specific mangling
    633  * remains the frontend's responsibility. Use this when filling
    634  * KitCgDecl.linkage_name for symbols that should interoperate with C entry
    635  * names, libc symbols, and linker entry lookup. */
    636 KIT_API KitSym kit_cg_c_linkage_name(KitCompiler*, KitSym source_name);
    637 
    638 /* ============================================================
    639  * Function Bodies and Locals
    640  * ============================================================ */
    641 
    642 KIT_API void kit_cg_func_begin(KitCg*, KitCgSym sym);
    643 KIT_API void kit_cg_func_begin_attrs(KitCg*, KitCgSym sym,
    644                                      KitCgFuncAttrs attrs);
    645 /* Enable stack-canary instrumentation for the current function. Call after
    646  * declaring parameters and before the first protected stack object is used.
    647  * Idempotent. A no-op when KitCodeOptions.stack_protector is NONE. CG snapshots
    648  * the target ABI guard, checks it before every subsequent return, and disables
    649  * sibling/tail exits for the function. */
    650 KIT_API void kit_cg_stack_protector_enable(KitCg*);
    651 KIT_API void kit_cg_func_end(KitCg*);
    652 
    653 /* Reclaim the storage of dead compiler temporaries. A frontend calls this at a
    654  * full-expression / statement boundary where it has consumed all values it
    655  * pushed (the value stack is empty); the single-pass -O0 backend then recycles
    656  * the frame homes of its per-subexpression temps, bounding the frame to
    657  * max-simultaneous-live temps. A no-op when the value stack is non-empty or the
    658  * backend does not recycle (optimizer / C-source targets). Purely an
    659  * optimization: omitting it only enlarges the frame. */
    660 KIT_API void kit_cg_reclaim_temps(KitCg*);
    661 
    662 typedef enum KitCgLocalFlag {
    663   KIT_CG_LOCALFLAG_NONE = 0,
    664   KIT_CG_LOCAL_ARTIFICIAL = 1u << 1,
    665   KIT_CG_LOCAL_OPTIMIZED_OUT = 1u << 2,
    666   KIT_CG_LOCAL_COMPILER_TEMP = 1u << 3,
    667   /* Force an addressable storage home even when the type is scalar. Frontends
    668    * use this for source objects whose accesses must remain memory operations
    669    * (for example C volatile automatic objects). */
    670   KIT_CG_LOCAL_MEMORY_REQUIRED = 1u << 4,
    671 } KitCgLocalFlag;
    672 
    673 typedef struct KitCgLocalAttrs {
    674   KitSym name;
    675   uint32_t align;            /* 0 = natural */
    676   uint32_t flags;            /* KitCgLocalFlag */
    677   KitCgDebugType debug_type; /* 0 = derive from local/param type */
    678 } KitCgLocalAttrs;
    679 
    680 KIT_API KitCgLocal kit_cg_local(KitCg*, KitCgTypeId type,
    681                                 KitCgLocalAttrs attrs);
    682 /* Declares a source parameter as a local handle. Parameters must be declared
    683  * in order before ordinary locals; therefore the first n parameter handles in
    684  * a function are also the first n local ids. */
    685 KIT_API KitCgLocal kit_cg_param(KitCg*, uint32_t index, KitCgTypeId type,
    686                                 KitCgLocalAttrs attrs);
    687 
    688 /* Pops a byte size and pushes a pointer to stack storage with at least align
    689  * alignment. The allocation lifetime is the current function activation. */
    690 KIT_API void kit_cg_alloca(KitCg*, uint32_t align, KitCgTypeId result_ptr_type);
    691 
    692 /* ============================================================
    693  * Control flow
    694  * ============================================================ */
    695 
    696 /* Structured control flow scopes.
    697  *
    698  * kit_cg_scope_begin / kit_cg_block_begin create statement scopes with no
    699  * result values. The *_value variants create single-result expression scopes;
    700  * result_type must be a valid non-void type id.
    701  *
    702  * Stack effects for a value scope:
    703  *   break(scope)       -> pop result, exit scope
    704  *   break_true(scope)  -> stack is [result, bool]; pop bool; if true, pop
    705  *                         result and exit; otherwise pop result
    706  *   break_false(scope) -> same but exit on false
    707  *   scope_end(scope)   -> TOS is the fallthrough result
    708  *
    709  * continue/continue_true/continue_false never carry a result; they jump to
    710  * the loop header, not the scope exit. */
    711 KIT_API KitCgScope kit_cg_scope_begin(KitCg*);
    712 KIT_API KitCgScope kit_cg_scope_begin_value(KitCg*, KitCgTypeId result_type);
    713 
    714 /* Like kit_cg_scope_begin but opens a forward-only block: break exits past
    715  * the scope; continue is not legal. This is the natural shape for `if`/
    716  * `if-else` (a wrapping block whose break is "skip the rest"), and lets
    717  * backends with structured control flow (Wasm) emit `block`/`end` directly
    718  * instead of recognizing arbitrary forward-only label-and-jump patterns. */
    719 KIT_API KitCgScope kit_cg_block_begin(KitCg*);
    720 KIT_API KitCgScope kit_cg_block_begin_value(KitCg*, KitCgTypeId result_type);
    721 
    722 /* Multi-value scopes: a block/loop that carries N params and/or N results
    723  * (the value-stack analogue of a Wasm multi-value block). params/results are
    724  * listed value-stack bottom -> top.
    725  *
    726  *   block_begin_sig: params stay on the value stack for the body to consume;
    727  *     break / scope_end carry `nresults` values across the exit edge.
    728  *   scope_begin_sig (loop): the API snapshots the `nparams` params off the
    729  *     stack into loop-param locals, then reloads them so every back edge sees
    730  *     the same shape. A back edge re-supplies fresh params via
    731  *     kit_cg_scope_store_params (which pops `nparams` into those locals, no
    732  *     jump) followed by a jump to kit_cg_scope_continue_label.
    733  *
    734  * kit_cg_scope_begin / kit_cg_block_begin are the nparams==0, nresults==0
    735  * special cases; the *_value variants are nparams==0, nresults==1.
    736  * Results must be valid non-void type ids. break, break_true, break_false, the
    737  * continue ops and scope_end all generalize to N values. */
    738 typedef struct KitCgScopeSig {
    739   const KitCgTypeId* params; /* value-stack bottom -> top */
    740   uint32_t nparams;
    741   const KitCgTypeId* results; /* value-stack bottom -> top */
    742   uint32_t nresults;
    743 } KitCgScopeSig;
    744 KIT_API KitCgScope kit_cg_scope_begin_sig(KitCg*,
    745                                           const KitCgScopeSig*); /*loop*/
    746 KIT_API KitCgScope kit_cg_block_begin_sig(KitCg*, const KitCgScopeSig*);
    747 /* Pop `nparams` values into the loop's param locals (bottom->top), without
    748  * jumping. The caller then jumps kit_cg_scope_continue_label to take the back
    749  * edge. Valid only on a loop scope (one opened with a continue label). */
    750 KIT_API void kit_cg_scope_store_params(KitCg*, KitCgScope);
    751 
    752 KIT_API void kit_cg_scope_end(KitCg*, KitCgScope);
    753 /* Close a scope whose fall-through is unreachable (its body ended in a
    754  * branch/return so there are no fall-through results to consume). Unlike
    755  * kit_cg_scope_end it does not pop results off the stack; the value stack must
    756  * already be at the scope's base depth. The scope's results (set by whatever
    757  * branch exited it) are pushed on exit, exactly as kit_cg_scope_end does. */
    758 KIT_API void kit_cg_scope_end_unreachable(KitCg*, KitCgScope);
    759 /* Expose the labels CG minted for this scope. Frontends that emit
    760  * unstructured `jump`/`branch` ops (rather than going through the
    761  * scope_break/scope_continue helpers) can use these to land control at
    762  * the scope's break/continue points — handy when the same backend needs
    763  * to translate label-targeted jumps back into structured `break;`/
    764  * `continue;` later (the C source target does this). */
    765 KIT_API KitCgLabel kit_cg_scope_break_label(KitCg*, KitCgScope);
    766 KIT_API KitCgLabel kit_cg_scope_continue_label(KitCg*, KitCgScope);
    767 KIT_API void kit_cg_break(KitCg*, KitCgScope);
    768 KIT_API void kit_cg_break_true(KitCg*, KitCgScope);
    769 KIT_API void kit_cg_break_false(KitCg*, KitCgScope);
    770 KIT_API void kit_cg_continue(KitCg*, KitCgScope);
    771 KIT_API void kit_cg_continue_true(KitCg*, KitCgScope);
    772 KIT_API void kit_cg_continue_false(KitCg*, KitCgScope);
    773 
    774 /* Unstructured labels and jumps. */
    775 KIT_API KitCgLabel kit_cg_label_new(KitCg*);
    776 KIT_API void kit_cg_label_place(KitCg*, KitCgLabel);
    777 KIT_API void kit_cg_jump(KitCg*, KitCgLabel);
    778 KIT_API void kit_cg_branch_true(KitCg*, KitCgLabel);
    779 KIT_API void kit_cg_branch_false(KitCg*, KitCgLabel);
    780 
    781 typedef struct KitCgSwitchCase {
    782   uint64_t value; /* bit pattern interpreted using selector_type */
    783   KitCgLabel label;
    784 } KitCgSwitchCase;
    785 
    786 typedef enum KitCgSwitchHint {
    787   KIT_CG_SWITCH_TARGET_DEFAULT,
    788   KIT_CG_SWITCH_BRANCH_CHAIN,
    789   KIT_CG_SWITCH_JUMP_TABLE,
    790 } KitCgSwitchHint;
    791 
    792 typedef struct KitCgSwitch {
    793   KitCgTypeId selector_type;
    794   KitCgLabel default_label;
    795   const KitCgSwitchCase* cases;
    796   uint32_t ncases;
    797   KitCgSwitchHint hint;
    798 } KitCgSwitch;
    799 
    800 /* Pops an integer selector and branches to the case whose value matches
    801  * it, or to default_label if none does. Mirrors the shape of C's
    802  * `switch (val) { case V1: ...; default: ...; }`. Frontends that want
    803  * jump-table dispatch (wasm br_table, computed-goto-style direct
    804  * threading) pass dense case values 0..N-1 — backends can detect the
    805  * shape and emit a real table; the C target lets the host compiler
    806  * decide. The hint is advisory; targets may ignore it. */
    807 KIT_API void kit_cg_switch(KitCg*, KitCgSwitch sw);
    808 
    809 /* Pushes the address of a label in the current function. Label addresses are
    810  * first-class pointer values for direct-threaded interpreters: they may be
    811  * stored, loaded, selected from tables, compared for equality, and consumed by
    812  * kit_cg_computed_goto. They are only valid within the defining function's
    813  * dynamic activation and must not be called or dereferenced as data. */
    814 KIT_API void kit_cg_push_label_addr(KitCg*, KitCgLabel, KitCgTypeId ptr_type);
    815 
    816 /* Pops a label address and branches to it. valid_targets must name the
    817  * non-empty closed set of labels the target may resolve to; targets use it
    818  * for validation, CFG construction, and branch-protection lowering. */
    819 KIT_API void kit_cg_computed_goto(KitCg*, const KitCgLabel* valid_targets,
    820                                   uint32_t ntargets);
    821 
    822 /* Terminates the current block with unreachable code. This is a real
    823  * terminator, not a side-effect intrinsic. */
    824 KIT_API void kit_cg_unreachable(KitCg*);
    825 
    826 /* ============================================================
    827  * Memory Access
    828  * ============================================================ */
    829 
    830 typedef enum KitCgMemAccessFlag {
    831   KIT_CG_MEM_NONE = 0,
    832   /* Access is an externally observable side effect and must not be merged,
    833    * removed, or reordered across other volatile accesses. */
    834   KIT_CG_MEM_VOLATILE = 1u << 0,
    835   /* Backend hint (loads only): emit a sign-extending narrow load when
    836    * supported. Frontends normally set KIT_CG_MEM_SOURCE_SIGNED and let
    837    * kit_cg_load derive this for byte/half integer loads; direct callers may
    838    * still set it when they already know the following use is sign-extension.
    839    * Ignored on stores and bit-fields. */
    840   KIT_CG_MEM_SEXT_LOAD = 1u << 1,
    841   /* The source-language object being accessed is a signed integer. KitCgTypeId
    842    * intentionally carries width/category, not C signedness, so this keeps the
    843    * source semantic fact separate from the backend SEXT-load hint above. */
    844   KIT_CG_MEM_SOURCE_SIGNED = 1u << 2,
    845 } KitCgMemAccessFlag;
    846 
    847 typedef struct KitCgMemAccess {
    848   KitCgTypeId type;       /* value type loaded/stored, or element type */
    849   uint32_t align;         /* 0 = natural for type */
    850   uint32_t address_space; /* normally inherited from pointer type */
    851   uint32_t flags;         /* KitCgMemAccessFlag */
    852 } KitCgMemAccess;
    853 
    854 /* ============================================================
    855  * Value stack: PLACES and VALUES
    856  * ============================================================
    857  *
    858  * Every stack entry is exactly one of two kinds, and each op below declares the
    859  * kinds it consumes and produces. The op enforces this: handing an op the wrong
    860  * kind is a usage error and panics. CG never *infers* the kind of a stack entry
    861  * or silently inserts a dereference — addressing is always built explicitly.
    862  *
    863  *   PLACE  — an addressable, typed location of an object (a local's storage, a
    864  *            global, or a computed `[base + index*scale + offset]`). Produced
    865  * by push_local / deref / field / elem; consumed by load / store / addr.
    866  *
    867  *   VALUE  — a scalar rvalue: an integer, float, pointer, or 128-bit scalar.
    868  *            Produced by push_int/float/null, push_symbol_addr,
    869  * push_local_addr, addr, and load; consumed by the arithmetic / call / branch
    870  * ops.
    871  *
    872  * Aggregates (records, arrays) are ALWAYS a PLACE — there is no aggregate
    873  * VALUE. Copying an aggregate is an explicit store/memcpy between places.
    874  *
    875  * The four building blocks of addressing:
    876  *   - push_local l : —            -> PLACE          (the local's storage)
    877  *   - addr         : PLACE        -> VALUE(ptr)     (address of the place)
    878  *   - deref        : VALUE(ptr)   -> PLACE          (the place the ptr names)
    879  *   - field i      : PLACE(record)-> PLACE(field)   (sub-object, by layout)
    880  *   - elem         : VALUE(ptr),index VALUE -> PLACE (element of an array/ptr)
    881  * From these, `*p` is `deref`, `p->f` is `deref; field`, `s.f` is `field`,
    882  * `a[i]` is `addr; <decay to *elem>; elem`, and `&x` is `addr`. */
    883 
    884 KIT_API void kit_cg_dup(KitCg*);
    885 KIT_API void kit_cg_dup2(KitCg*); /* duplicates the top two slots */
    886 KIT_API void kit_cg_swap(KitCg*);
    887 KIT_API void kit_cg_drop(KitCg*);
    888 KIT_API void kit_cg_rot3(KitCg*); /* [..., a, b, c] -> [..., b, c, a] */
    889 
    890 typedef struct KitCgSlotInfo {
    891   KitCgTypeId cg_type;
    892   const void* lang_type;
    893   uint16_t lang_flags;
    894 } KitCgSlotInfo;
    895 
    896 /* Inspect and update frontend-owned facts on value-stack slots. CG treats
    897  * lang_type as opaque and lang_flags as frontend-defined bits; stack-producing
    898  * operations clear them, while structural stack operations copy/move them with
    899  * the slot. depth_from_top 0 names TOS.
    900  *
    901  * kit_cg_slot_info returns the whole {cg_type, lang_type, lang_flags} fact by
    902  * value (a zeroed struct when the slot does not exist). The narrower accessors
    903  * read one field directly with no copy and return zero/NULL when the slot does
    904  * not exist; prefer them on hot paths that need a single fact. */
    905 KIT_API KitCgSlotInfo kit_cg_slot_info(KitCg*, uint32_t depth_from_top);
    906 KIT_API KitCgTypeId kit_cg_slot_cg_type(KitCg*, uint32_t depth_from_top);
    907 KIT_API const void* kit_cg_slot_lang_type(KitCg*, uint32_t depth_from_top);
    908 KIT_API uint16_t kit_cg_slot_lang_flags(KitCg*, uint32_t depth_from_top);
    909 KIT_API void kit_cg_retag_top(KitCg*, const void* lang_type,
    910                               uint16_t lang_flags);
    911 KIT_API void kit_cg_retag_at(KitCg*, uint32_t depth_from_top,
    912                              const void* lang_type, uint16_t lang_flags);
    913 KIT_API void kit_cg_set_top_flags(KitCg*, uint16_t set, uint16_t clear);
    914 
    915 /* The current value-stack depth. Lets a frontend record a base depth and later
    916  * drop back to it (e.g. discarding the operands a Wasm polymorphic/unreachable
    917  * region left behind). */
    918 KIT_API uint32_t kit_cg_stack_depth(KitCg*);
    919 
    920 typedef struct KitCgConstInt {
    921   uint64_t lo;       /* low bits, always truncated to width */
    922   uint64_t hi;       /* high bits for width > 64 */
    923   uint16_t width;    /* 1..128 for integer constants */
    924   uint8_t is_signed; /* interpretation hint for convenience queries */
    925   uint8_t known;     /* 0 => not a compile-time integer constant */
    926 } KitCgConstInt;
    927 
    928 /* Suppress target emission while preserving value-stack shape and stack-owned
    929  * constant facts. Nested pushes are allowed; pop diagnoses underflow. */
    930 KIT_API void kit_cg_unevaluated_push(KitCg*);
    931 KIT_API void kit_cg_unevaluated_pop(KitCg*);
    932 
    933 /* Width-complete integer-constant query. Reads the stack-side constant payload,
    934  * not the emitted operand shape, and does not pop the value. */
    935 KIT_API int kit_cg_top_const_int_ex(KitCg*, KitCgConstInt* out_value);
    936 
    937 /* Convenience query for constants representable as one 64-bit lane. */
    938 KIT_API int kit_cg_top_const_i64(KitCg*, int64_t* out_value);
    939 
    940 /* Push a scalar integer VALUE with an explicit width-complete constant payload.
    941  * The value is truncated to the destination type width when that width is
    942  * integer-like and known. */
    943 KIT_API void kit_cg_push_const_int(KitCg*, KitCgTypeId type,
    944                                    const KitCgConstInt* value);
    945 
    946 /* Compatibility wrapper for older callers that only need a signed 64-bit
    947  * result. */
    948 KIT_API int kit_cg_top_const_int(KitCg*, int64_t* out_value);
    949 
    950 /* Push a scalar VALUE. */
    951 KIT_API void kit_cg_push_int(KitCg*, uint64_t value, KitCgTypeId type);
    952 KIT_API void kit_cg_push_float(KitCg*, double value, KitCgTypeId type);
    953 KIT_API void kit_cg_push_null(KitCg*, KitCgTypeId ptr_type);
    954 /* Push the PLACE that is the local's storage. Stack: [] -> [place]. */
    955 KIT_API void kit_cg_push_local(KitCg*, KitCgLocal local);
    956 /* Push the local's address as a pointer VALUE (sugar for push_local; addr).
    957  * Stack: [] -> [ptr]. */
    958 KIT_API void kit_cg_push_local_addr(KitCg*, KitCgLocal local);
    959 
    960 /* Anonymous immutable data. Returns a local readonly object symbol; callers
    961  * can materialize its address (a VALUE) with push_symbol_addr. pointee_type
    962  * describes the logical value at that address, enabling const_data +
    963  * push_symbol_addr + deref + load to materialize arbitrary-width constants. */
    964 KIT_API KitCgSym kit_cg_const_data(KitCg*, const uint8_t* data, size_t len,
    965                                    uint32_t align, KitCgTypeId pointee_type);
    966 
    967 /* Push &sym + addend as a pointer VALUE. For TLS objects this means the address
    968  * of the current thread's instance; the target chooses LE/IE/GD/TLVP or
    969  * equivalent lowering from the symbol attrs and output mode. Stack: [] ->
    970  * [ptr].
    971  */
    972 KIT_API void kit_cg_push_symbol_addr(KitCg*, KitCgSym sym, int64_t addend);
    973 
    974 /* PLACE -> VALUE(ptr): the address of the place (e.g. `&x`, or to pass/escape).
    975  * Stack: [place] -> [ptr]. Errors if TOS is not a PLACE. */
    976 KIT_API void kit_cg_addr(KitCg*);
    977 
    978 /* VALUE(ptr) -> PLACE: the explicit pointer->place transition. The produced
    979  * place is `*(ptr + offset bytes)`; `offset` is a byte displacement folded into
    980  * the addressing mode (0 for a plain `*p`). Stack: [ptr] -> [place]. Errors if
    981  * TOS is not a pointer VALUE — a PLACE must be turned into a pointer with
    982  * `addr` first; the op never guesses. */
    983 KIT_API void kit_cg_deref(KitCg*, int64_t offset);
    984 
    985 /* PLACE(record) -> PLACE(field): project a record place to one of its fields by
    986  * index; the byte offset and field type come from the record's layout (CG owns
    987  * layout). Stack: [place] -> [place]. Errors if TOS is not a record PLACE — for
    988  * `p->f` the frontend does `deref; field`, not `field` on a pointer.
    989  *
    990  * Bit-field PLACE subkind: when field_index names a bit-field, `field` projects
    991  * to a *bit-field place* — a PLACE that addresses the field's storage unit and
    992  * additionally carries the bit-field descriptor (bit offset/width, storage-unit
    993  * size, signedness) from the record layout. A bit-field place is a place like
    994  * any other: a plain `load` reads the field (extract + sign/zero-extend) and a
    995  * plain `store` writes it (read-modify-write insert). There is no separate
    996  * bit-field memop and no bit-field rider on KitCgMemAccess; the place is the
    997  * one and only carrier of bit-field geometry. `addr` and aggregate access on a
    998  * bit-field place are not legal (a bit-field has no addressable byte location);
    999  * the frontend rejects `&` / `sizeof` on a bit-field before reaching CG. */
   1000 KIT_API void kit_cg_field(KitCg*, uint32_t field_index);
   1001 
   1002 /* PLACE -> PLACE: project to a byte-offset subobject with a frontend-supplied
   1003  * field type. This is the layout-known counterpart to kit_cg_field: CG does no
   1004  * record lookup, but still folds byte_offset into the place operand when the
   1005  * target addressing mode can carry it. Bit-field geometry, if any, is attached
   1006  * separately with kit_cg_field_bits. */
   1007 KIT_API void kit_cg_field_at(KitCg*, int64_t byte_offset,
   1008                              KitCgTypeId field_type);
   1009 
   1010 /* PLACE -> PLACE(bit-field): tag the TOS place as a bit-field place carrying
   1011  * the given bit geometry. This is the manual-addressing counterpart to the
   1012  * implicit bit-field projection `field` performs: a frontend that builds the
   1013  * storage-unit place itself (deref/elem onto the storage unit) calls this to
   1014  * attach the descriptor, after which a plain load/store extracts/inserts the
   1015  * field. The place must address the field's storage unit. bit_storage_size is
   1016  * the storage- unit size in bytes; bit_signed selects signed extraction on
   1017  * load. Stack: [place] -> [place]. There is no separate bit-field memop — the
   1018  * place is the one carrier of bit-field geometry. */
   1019 KIT_API void kit_cg_field_bits(KitCg*, uint16_t bit_offset, uint16_t bit_width,
   1020                                uint32_t bit_storage_size, int bit_signed);
   1021 
   1022 /* (VALUE(ptr to T), index VALUE) -> PLACE(T): the element at `*(base +
   1023  * index*sizeof(T) + offset)`. The index is scaled by sizeof(T) (the pointer's
   1024  * pointee) and the constant `offset` byte displacement is folded in, so the
   1025  * place is a single `[base + index*scale + offset]` addressing mode (base and
   1026  * index dynamic; scale and offset constant). The base is a pointer VALUE; an
   1027  * array is decayed to a pointer (`addr` + cast to *T) by the frontend first.
   1028  * Stack: [base, index] -> [place]. Errors if the base is not a pointer VALUE.
   1029  */
   1030 KIT_API void kit_cg_elem(KitCg*, int64_t offset);
   1031 
   1032 /* Like kit_cg_elem, but the index is scaled by an EXPLICIT `elem_size` instead
   1033  * of the base pointer's pointee size, and the resulting place's access type is
   1034  * the base pointee. Lets a frontend build `[base + index*elem_size + offset]`
   1035  * where the index stride (the containing array's element size) differs from the
   1036  * accessed sub-object's size — e.g. `arr[i].f` strides by sizeof(elem) while
   1037  * accessing the field `f`. The caller bitcasts the base to the access type
   1038  * first. Stack: [base, index] -> [place]. */
   1039 KIT_API void kit_cg_elem_scaled(KitCg*, uint32_t elem_size, int64_t offset);
   1040 
   1041 /* Load a VALUE from a PLACE / store a VALUE into a PLACE. The PLACE carries all
   1042  * addressing (built via push_local / deref / field / elem); the memop takes no
   1043  * effective-address rider. When the PLACE is a bit-field place (produced by
   1044  * `field` on a bit-field), the load/store extract/insert the field per the
   1045  * descriptor the place carries — `access` then describes only the access type,
   1046  * alignment, and volatility, never bit geometry. Both error if the addressed
   1047  * operand is not a PLACE — a pointer VALUE must be `deref`'d first.
   1048  *
   1049  * Stack effects:
   1050  *   load:  [place]        -> [value]
   1051  *   store: [place, value] -> []
   1052  *   store_keep: [place, value] -> [value] */
   1053 KIT_API void kit_cg_load(KitCg*, KitCgMemAccess access);
   1054 KIT_API void kit_cg_store(KitCg*, KitCgMemAccess access);
   1055 KIT_API void kit_cg_store_keep(KitCg*, KitCgMemAccess access);
   1056 
   1057 /* ============================================================
   1058  * ABI variadic argument access
   1059  * ============================================================ */
   1060 
   1061 /* This models only target calling-convention varargs; higher-level rest
   1062  * parameters should lower to explicit aggregate parameters before reaching CG.
   1063  *
   1064  * The frontend allocates a local of KIT_CG_BUILTIN_VARARG_STATE and pushes
   1065  * that local's address before each operation. The implementation reads and
   1066  * writes the state in memory according to the target ABI. */
   1067 KIT_API void kit_cg_vararg_start(KitCg*); /* pop &state */
   1068 KIT_API void kit_cg_vararg_next(KitCg*,
   1069                                 KitCgTypeId type); /* pop &state; push value */
   1070 KIT_API void kit_cg_vararg_end(KitCg*);            /* pop &state             */
   1071 KIT_API void kit_cg_vararg_copy(KitCg*);           /* pop &dst, &src         */
   1072 
   1073 /* ============================================================
   1074  * Integer Operations
   1075  * ============================================================ */
   1076 
   1077 typedef enum KitCgIntBinOp {
   1078   KIT_CG_INT_ADD,
   1079   KIT_CG_INT_SUB,
   1080   KIT_CG_INT_MUL,
   1081   KIT_CG_INT_SDIV,
   1082   KIT_CG_INT_UDIV,
   1083   KIT_CG_INT_SREM,
   1084   KIT_CG_INT_UREM,
   1085   KIT_CG_INT_AND,
   1086   KIT_CG_INT_OR,
   1087   KIT_CG_INT_XOR,
   1088   KIT_CG_INT_SHL,
   1089   KIT_CG_INT_LSHR,
   1090   KIT_CG_INT_ASHR,
   1091 } KitCgIntBinOp;
   1092 
   1093 typedef enum KitCgIntOpFlag {
   1094   KIT_CG_INTOP_NONE = 0,
   1095   KIT_CG_INTOP_NSW = 1u << 0,
   1096   KIT_CG_INTOP_NUW = 1u << 1,
   1097   KIT_CG_INTOP_EXACT = 1u << 2,
   1098   /* Overflow semantics are explicit because integer types are width-only.
   1099    * Signed and unsigned trap/saturate flags are mutually exclusive. */
   1100   KIT_CG_INTOP_TRAP_SIGNED_OVERFLOW = 1u << 3,
   1101   KIT_CG_INTOP_TRAP_UNSIGNED_OVERFLOW = 1u << 4,
   1102   KIT_CG_INTOP_SATURATE_SIGNED = 1u << 5,
   1103   KIT_CG_INTOP_SATURATE_UNSIGNED = 1u << 6,
   1104 } KitCgIntOpFlag;
   1105 
   1106 typedef enum KitCgIntCmpOp {
   1107   KIT_CG_INT_EQ,
   1108   KIT_CG_INT_NE,
   1109   KIT_CG_INT_LT_S,
   1110   KIT_CG_INT_LE_S,
   1111   KIT_CG_INT_GT_S,
   1112   KIT_CG_INT_GE_S,
   1113   KIT_CG_INT_LT_U,
   1114   KIT_CG_INT_LE_U,
   1115   KIT_CG_INT_GT_U,
   1116   KIT_CG_INT_GE_U,
   1117 } KitCgIntCmpOp;
   1118 
   1119 typedef enum KitCgIntUnOp {
   1120   KIT_CG_INT_NEG,
   1121   KIT_CG_INT_NOT,
   1122   KIT_CG_INT_BNOT,
   1123 } KitCgIntUnOp;
   1124 
   1125 KIT_API void kit_cg_int_binop(KitCg*, KitCgIntBinOp, uint32_t flags);
   1126 KIT_API void kit_cg_int_unop(KitCg*, KitCgIntUnOp, uint32_t flags);
   1127 KIT_API void kit_cg_int_cmp(KitCg*, KitCgIntCmpOp);
   1128 
   1129 /* ============================================================
   1130  * Floating-Point Operations
   1131  * ============================================================ */
   1132 
   1133 typedef enum KitCgFpBinOp {
   1134   KIT_CG_FP_ADD,
   1135   KIT_CG_FP_SUB,
   1136   KIT_CG_FP_MUL,
   1137   KIT_CG_FP_DIV,
   1138   /* No FP remainder: it is a libcall (fmod/fmodf/fmodl), which the frontend
   1139    * emits directly. */
   1140 } KitCgFpBinOp;
   1141 
   1142 typedef enum KitCgFpCmpOp {
   1143   KIT_CG_FP_OEQ,
   1144   KIT_CG_FP_ONE,
   1145   KIT_CG_FP_OLT,
   1146   KIT_CG_FP_OLE,
   1147   KIT_CG_FP_OGT,
   1148   KIT_CG_FP_OGE,
   1149   KIT_CG_FP_UEQ,
   1150   KIT_CG_FP_UNE,
   1151   KIT_CG_FP_ULT,
   1152   KIT_CG_FP_ULE,
   1153   KIT_CG_FP_UGT,
   1154   KIT_CG_FP_UGE,
   1155 } KitCgFpCmpOp;
   1156 
   1157 typedef enum KitCgFpUnOp {
   1158   KIT_CG_FP_NEG,
   1159 } KitCgFpUnOp;
   1160 
   1161 typedef enum KitCgFpFlag {
   1162   KIT_CG_FP_NONE = 0,
   1163   KIT_CG_FP_REASSOC = 1u << 0,
   1164   KIT_CG_FP_NO_NANS = 1u << 1,
   1165   KIT_CG_FP_NO_INFS = 1u << 2,
   1166   KIT_CG_FP_NO_SIGNED_ZEROS = 1u << 3,
   1167   KIT_CG_FP_ALLOW_RECIP = 1u << 4,
   1168   KIT_CG_FP_APPROX = 1u << 5,
   1169 } KitCgFpFlag;
   1170 
   1171 KIT_API void kit_cg_fp_binop(KitCg*, KitCgFpBinOp, uint32_t flags);
   1172 KIT_API void kit_cg_fp_unop(KitCg*, KitCgFpUnOp, uint32_t flags);
   1173 KIT_API void kit_cg_fp_cmp(KitCg*, KitCgFpCmpOp);
   1174 
   1175 /* ============================================================
   1176  * Conversions
   1177  * ============================================================ */
   1178 
   1179 typedef enum KitCgRounding {
   1180   KIT_CG_ROUND_DEFAULT,
   1181   KIT_CG_ROUND_NEAREST_EVEN,
   1182   KIT_CG_ROUND_TOWARD_ZERO,
   1183   KIT_CG_ROUND_DOWN,
   1184   KIT_CG_ROUND_UP,
   1185 } KitCgRounding;
   1186 
   1187 KIT_API void kit_cg_sext(KitCg*, KitCgTypeId dst);
   1188 KIT_API void kit_cg_zext(KitCg*, KitCgTypeId dst);
   1189 KIT_API void kit_cg_trunc(KitCg*, KitCgTypeId dst);
   1190 KIT_API void kit_cg_ptr_to_int(KitCg*, KitCgTypeId dst);
   1191 KIT_API void kit_cg_int_to_ptr(KitCg*, KitCgTypeId dst);
   1192 KIT_API void kit_cg_bitcast(KitCg*, KitCgTypeId dst);
   1193 KIT_API void kit_cg_fpext(KitCg*, KitCgTypeId dst);
   1194 KIT_API void kit_cg_fptrunc(KitCg*, KitCgTypeId dst);
   1195 KIT_API void kit_cg_sint_to_float(KitCg*, KitCgTypeId dst,
   1196                                   KitCgRounding rounding);
   1197 KIT_API void kit_cg_uint_to_float(KitCg*, KitCgTypeId dst,
   1198                                   KitCgRounding rounding);
   1199 KIT_API void kit_cg_float_to_sint(KitCg*, KitCgTypeId dst,
   1200                                   KitCgRounding rounding);
   1201 KIT_API void kit_cg_float_to_uint(KitCg*, KitCgTypeId dst,
   1202                                   KitCgRounding rounding);
   1203 
   1204 /* ============================================================
   1205  * Calls and Returns
   1206  * ============================================================ */
   1207 
   1208 /* Tail-call policy for a call site.
   1209  *
   1210  * A tail call is a TERMINATOR: it ends the current function. It pushes no
   1211  * result onto the value stack, and the caller must not emit kit_cg_ret
   1212  * after it — the call is the return.
   1213  *
   1214  * Two distinct conditions govern whether a tail call is legal:
   1215  *
   1216  *  - Signature match is a PRECONDITION the frontend must guarantee: the
   1217  *    callee's return type must be ABI-compatible with the enclosing
   1218  *    function's declared return type, and the call must sit in return
   1219  *    position. A violation is a frontend bug; CG aborts (compiler_panic)
   1220  *    regardless of policy — it is never treated as a fallback case.
   1221  *
   1222  *  - ABI realizability is DISCOVERED during emission and is target-specific:
   1223  *    can control transfer to the callee while reusing (and tearing down) the
   1224  *    current frame, with the callee's outgoing argument area and return
   1225  *    mechanism fitting the space the caller itself received? sret and
   1226  *    variadic are NOT inherent blockers — an sret return is forwarded via the
   1227  *    function's own incoming sret pointer, and a variadic callee is fine when
   1228  *    its argument area fits the caller's incoming area. The usual blocker is
   1229  *    an outgoing argument area that exceeds that space; some are arch-specific
   1230  *    (e.g. wasm packs varargs into a caller-frame buffer that a sibling call
   1231  *    would dangle). This is what ALLOWED vs MUST governs.
   1232  */
   1233 typedef enum KitCgTailPolicy {
   1234   /* Ordinary call. Result is pushed; not a terminator. */
   1235   KIT_CG_TAIL_DEFAULT,
   1236   /* Tail-call (terminator) if ABI-realizable; otherwise silently emit an
   1237    * ordinary call and synthesize the caller's return of the result. Never
   1238    * fails for realizability. */
   1239   KIT_CG_TAIL_ALLOWED,
   1240   /* Tail-call (terminator); if not ABI-realizable, CG fails with a
   1241    * diagnostic naming the reason. Never silently degrades to an ordinary
   1242    * call. */
   1243   KIT_CG_TAIL_MUST,
   1244 } KitCgTailPolicy;
   1245 
   1246 typedef enum KitCgCallFlag {
   1247   KIT_CG_CALL_NONE = 0,
   1248   KIT_CG_CALL_COLD = 1u << 0,
   1249 } KitCgCallFlag;
   1250 
   1251 typedef struct KitCgCallAttrs {
   1252   KitCgTailPolicy tail;
   1253   uint32_t flags; /* KitCgCallFlag */
   1254   KitCgInlinePolicy inline_policy;
   1255 } KitCgCallAttrs;
   1256 
   1257 /* kit_cg_call pops a computed function pointer plus nargs arguments.
   1258  * kit_cg_call_symbol emits a direct call to the declared function symbol,
   1259  * allowing the backend/linker to choose PLT/stub/IAT/direct/IFUNC handling.
   1260  *
   1261  * For tail policies (see KitCgTailPolicy): the call is a terminator that
   1262  * pushes no result. A MUST tail call that is not ABI-realizable fails with a
   1263  * diagnostic; an ALLOWED tail call that is not realizable silently degrades
   1264  * to an ordinary call followed by a synthesized return of the result. A
   1265  * tail call whose callee return type is incompatible with the enclosing
   1266  * function's return type is a frontend bug and aborts under any policy.
   1267  *
   1268  * Results: a non-tail call to a value-returning callee pushes the callee's
   1269  * single result onto the stack (TOS). A void callee pushes nothing. */
   1270 KIT_API void kit_cg_call(KitCg*, uint32_t nargs, KitCgTypeId fn_type,
   1271                          KitCgCallAttrs attrs);
   1272 KIT_API void kit_cg_call_symbol(KitCg*, KitCgSym sym, uint32_t nargs,
   1273                                 KitCgCallAttrs attrs);
   1274 /* Returns from the current function. Pops the enclosing function's single
   1275  * result value from TOS, or nothing for a void function. This is the single
   1276  * return entry point. */
   1277 KIT_API void kit_cg_ret(KitCg*);
   1278 
   1279 /* ============================================================
   1280  * Intrinsics
   1281  * ============================================================ */
   1282 
   1283 typedef enum KitCgIntrinsic {
   1284   KIT_CG_INTRIN_TRAP,
   1285   KIT_CG_INTRIN_CLZ, /* zero input returns bit width     */
   1286   KIT_CG_INTRIN_CTZ, /* zero input returns bit width     */
   1287   KIT_CG_INTRIN_POPCOUNT,
   1288   KIT_CG_INTRIN_BSWAP,
   1289   KIT_CG_INTRIN_SETJMP,         /* pop &buf; push i32              */
   1290   KIT_CG_INTRIN_LONGJMP,        /* pop &buf, val; no return        */
   1291   KIT_CG_INTRIN_SADD_OVERFLOW,  /* pop a, b; push result, overflow */
   1292   KIT_CG_INTRIN_UADD_OVERFLOW,  /* pop a, b; push result, overflow */
   1293   KIT_CG_INTRIN_SSUB_OVERFLOW,  /* pop a, b; push result, overflow */
   1294   KIT_CG_INTRIN_USUB_OVERFLOW,  /* pop a, b; push result, overflow */
   1295   KIT_CG_INTRIN_SMUL_OVERFLOW,  /* pop a, b; push result, overflow */
   1296   KIT_CG_INTRIN_UMUL_OVERFLOW,  /* pop a, b; push result, overflow */
   1297   KIT_CG_INTRIN_FMA,            /* pop a, b, c; push a * b + c     */
   1298   KIT_CG_INTRIN_PREFETCH,       /* pop addr; no result             */
   1299   KIT_CG_INTRIN_EXPECT,         /* pop val, expected; push val     */
   1300   KIT_CG_INTRIN_ASSUME_ALIGNED, /* pop ptr; push aligned ptr       */
   1301   KIT_CG_INTRIN_SYSCALL,        /* pop nr, args...; push long      */
   1302   KIT_CG_INTRIN_IRQ_SAVE,       /* push unsigned long              */
   1303   KIT_CG_INTRIN_IRQ_RESTORE,    /* pop prev                        */
   1304   KIT_CG_INTRIN_IRQ_DISABLE,
   1305   KIT_CG_INTRIN_IRQ_ENABLE,
   1306   KIT_CG_INTRIN_DMB, /* pop KitCgBarrierScope         */
   1307   KIT_CG_INTRIN_DSB, /* pop KitCgBarrierScope         */
   1308   KIT_CG_INTRIN_ISB,
   1309   KIT_CG_INTRIN_DCACHE_CLEAN, /* pop ptr, size                   */
   1310   KIT_CG_INTRIN_DCACHE_INVALIDATE,
   1311   KIT_CG_INTRIN_DCACHE_CLEAN_INVALIDATE,
   1312   KIT_CG_INTRIN_ICACHE_INVALIDATE,
   1313   KIT_CG_INTRIN_CPU_NOP,
   1314   KIT_CG_INTRIN_CPU_YIELD,
   1315   KIT_CG_INTRIN_WFI,
   1316   KIT_CG_INTRIN_WFE,         /* arm/aarch64 only                */
   1317   KIT_CG_INTRIN_SEV,         /* arm/aarch64 only                */
   1318   KIT_CG_INTRIN_CORO_SWITCH, /* pop from, to, value; push value */
   1319   /* Frame-pointer-chain introspection (GCC __builtin_frame_address /
   1320    * __builtin_return_address). The level is a compile-time constant passed as a
   1321    * single immediate operand (nargs == 1); level 0 names the current frame.
   1322    * Both push a void*. Lowered as an unrolled FP walk; targets with no frame
   1323    * pointer (wasm) report unsupported. */
   1324   KIT_CG_INTRIN_FRAME_ADDRESS,  /* pop level(u32 const); push void* */
   1325   KIT_CG_INTRIN_RETURN_ADDRESS, /* pop level(u32 const); push void* */
   1326   /* Read the target cycle/timestamp counter (GCC/Clang
   1327    * __builtin_readcyclecounter). No operands; pushes an unsigned 64-bit value.
   1328    * Lowered to the native counter read (x86 RDTSC, aarch64 MRS CNTVCT_EL0,
   1329    * riscv64 RDCYCLE). Targets without a single-register 64-bit counter read
   1330    * report unsupported. */
   1331   KIT_CG_INTRIN_READCYCLECOUNTER, /* push u64 */
   1332   /* High half of a full-width integer product. Both pop two equal-width
   1333    * integer operands and push a result of that width. SMUL_HIGH interprets
   1334    * both operands as two's-complement signed; UMUL_HIGH is unsigned. */
   1335   KIT_CG_INTRIN_SMUL_HIGH,
   1336   KIT_CG_INTRIN_UMUL_HIGH,
   1337 } KitCgIntrinsic;
   1338 
   1339 typedef enum KitCgBarrierScope {
   1340   KIT_CG_BARRIER_FULL,
   1341   KIT_CG_BARRIER_INNER,
   1342   KIT_CG_BARRIER_INNER_STORE,
   1343   KIT_CG_BARRIER_OUTER,
   1344   KIT_CG_BARRIER_OUTER_STORE,
   1345   KIT_CG_BARRIER_NON_SHARE,
   1346 } KitCgBarrierScope;
   1347 
   1348 /* Pops nargs operands. result_type must be a valid type id; the void builtin
   1349  * means no result is pushed. Overflow intrinsics push two values: result,
   1350  * overflow_bool regardless of result_type. Syscall uses nargs = argc + 1: the
   1351  * syscall number plus 0..6 long arguments. Runtime-extension intrinsics mirror
   1352  * rt/include/kit/{syscall,baremetal,coro}.h and must diagnose targets where
   1353  * the primitive has no legal lowering. */
   1354 KIT_API void kit_cg_intrinsic(KitCg*, KitCgIntrinsic, uint32_t nargs,
   1355                               KitCgTypeId result_type);
   1356 
   1357 /* Capability query for kit_cg_intrinsic: true when the selected target has a
   1358  * legal lowering for this intrinsic (see kit_cg_target_supports_call_conv for
   1359  * the contract). Frontends test this before requesting a baremetal/CPU
   1360  * intrinsic so they can emit their own unsupported-feature diagnostic instead
   1361  * of tripping the CG fatal. */
   1362 KIT_API int kit_cg_target_supports_intrinsic(KitCompiler*, KitCgIntrinsic);
   1363 
   1364 /* ============================================================
   1365  * Fixed-Sized Memory Operations
   1366  * ============================================================ */
   1367 
   1368 /* Stack:
   1369  *   memcpy/memmove: [dst, src] -> []
   1370  *   memset:         [dst]      -> [] */
   1371 KIT_API void kit_cg_memcpy(KitCg*, uint64_t size, KitCgMemAccess dst,
   1372                            KitCgMemAccess src);
   1373 KIT_API void kit_cg_memmove(KitCg*, uint64_t size, KitCgMemAccess dst,
   1374                             KitCgMemAccess src);
   1375 KIT_API void kit_cg_memset(KitCg*, uint8_t val, uint64_t size,
   1376                            KitCgMemAccess dst);
   1377 
   1378 /* ============================================================
   1379  * Atomics
   1380  * ============================================================ */
   1381 
   1382 typedef enum KitCgAtomicOp {
   1383   KIT_CG_ATOMIC_XCHG,
   1384   KIT_CG_ATOMIC_ADD,
   1385   KIT_CG_ATOMIC_SUB,
   1386   KIT_CG_ATOMIC_AND,
   1387   KIT_CG_ATOMIC_OR,
   1388   KIT_CG_ATOMIC_XOR,
   1389   KIT_CG_ATOMIC_NAND,
   1390 } KitCgAtomicOp;
   1391 
   1392 typedef enum KitCgMemOrder {
   1393   KIT_CG_MO_RELAXED,
   1394   KIT_CG_MO_CONSUME,
   1395   KIT_CG_MO_ACQUIRE,
   1396   KIT_CG_MO_RELEASE,
   1397   KIT_CG_MO_ACQ_REL,
   1398   KIT_CG_MO_SEQ_CST,
   1399 } KitCgMemOrder;
   1400 
   1401 KIT_API int kit_cg_atomic_is_legal(KitCompiler*, KitCgMemAccess access,
   1402                                    KitCgMemOrder order);
   1403 KIT_API int kit_cg_atomic_is_lock_free(KitCompiler*, KitCgMemAccess access);
   1404 KIT_API void kit_cg_atomic_load(KitCg*, KitCgMemAccess access,
   1405                                 KitCgMemOrder order);
   1406 KIT_API void kit_cg_atomic_store(KitCg*, KitCgMemAccess access,
   1407                                  KitCgMemOrder order);
   1408 KIT_API void kit_cg_atomic_rmw(KitCg*, KitCgMemAccess access, KitCgAtomicOp,
   1409                                KitCgMemOrder order);
   1410 /* Stack: [ptr, expected, desired] -> [prior, ok_bool]. */
   1411 KIT_API void kit_cg_atomic_cmpxchg(KitCg*, KitCgMemAccess access,
   1412                                    KitCgMemOrder success, KitCgMemOrder failure,
   1413                                    int weak);
   1414 KIT_API void kit_cg_atomic_fence(KitCg*, KitCgMemOrder);
   1415 
   1416 /* ============================================================
   1417  * Inline Assembly
   1418  * ============================================================ */
   1419 
   1420 typedef enum KitCgAsmDir {
   1421   KIT_CG_ASM_IN,
   1422   KIT_CG_ASM_OUT,
   1423   KIT_CG_ASM_INOUT,
   1424 } KitCgAsmDir;
   1425 
   1426 typedef enum KitCgAsmFlag {
   1427   KIT_CG_ASM_NONE = 0,
   1428   KIT_CG_ASM_VOLATILE = 1u << 0,
   1429   KIT_CG_ASM_PURE = 1u << 1,
   1430   KIT_CG_ASM_NOMEM = 1u << 2,
   1431   KIT_CG_ASM_READONLY = 1u << 3,
   1432   KIT_CG_ASM_PRESERVES_FLAGS = 1u << 4,
   1433   KIT_CG_ASM_NOSTACK = 1u << 5,
   1434   KIT_CG_ASM_NORETURN = 1u << 6,
   1435 } KitCgAsmFlag;
   1436 
   1437 typedef enum KitCgAsmClobberAbiSet {
   1438   KIT_CG_ASM_CLOBBER_ABI_NONE = 0,
   1439   KIT_CG_ASM_CLOBBER_ABI_CALLER_SAVED = 1u << 0,
   1440   /* Every callee-saved register of the target ABI. The compiler preserves them
   1441    * across the asm block (prologue/epilogue save on the optimizer path, a
   1442    * per-block spill on the single-pass path) just as it would for named
   1443    * callee-saved clobbers — an arch-neutral way to say "this asm trashes the
   1444    * callee-saved register file". */
   1445   KIT_CG_ASM_CLOBBER_ABI_CALLEE_SAVED = 1u << 1,
   1446 } KitCgAsmClobberAbiSet;
   1447 
   1448 typedef struct KitCgAsmOperand {
   1449   KitSym constraint; /* interned target constraint string */
   1450   KitSym name;       /* interned symbolic operand name; 0 if absent */
   1451   KitCgTypeId type;
   1452   /* Explicit hard register this operand must occupy, named by its target
   1453    * spelling ("r10", "x8", "a7", ...); 0 when unconstrained. Set by a frontend
   1454    * for a GNU local register variable (`register T x __asm__("r10")`) used as
   1455    * an operand. The name is opaque to the frontend and CG — only the target's
   1456    * register file resolves it to a physical register. */
   1457   KitSym reg;
   1458   uint8_t dir; /* KitCgAsmDir */
   1459   uint8_t pad[3];
   1460 } KitCgAsmOperand;
   1461 
   1462 typedef struct KitCgInlineAsm {
   1463   KitSym tmpl;
   1464   const KitCgAsmOperand* outputs;
   1465   uint32_t noutputs;
   1466   const KitCgAsmOperand* inputs;
   1467   uint32_t ninputs;
   1468   const KitSym* clobbers;
   1469   uint32_t nclobbers;
   1470   uint32_t flags;            /* KitCgAsmFlag */
   1471   uint32_t clobber_abi_sets; /* KitCgAsmClobberAbiSet */
   1472 } KitCgInlineAsm;
   1473 
   1474 /* Inputs are popped in declaration order. Outputs are pushed in declaration
   1475  * order as fresh values after the asm block. INOUT outputs consume one
   1476  * initial value each after the explicit inputs, in output declaration order;
   1477  * tied operands, earlyclobber, register classes, explicit registers,
   1478  * immediates, memory operands, and target-specific alternatives are expressed
   1479  * in the per-operand constraint string. Template, constraints, and clobbers
   1480  * are pre-interned strings. clobber_abi_sets names target-defined ABI register
   1481  * sets such as all caller-saved registers. */
   1482 KIT_API void kit_cg_inline_asm(KitCg*, KitCgInlineAsm asm_block);
   1483 KIT_API void kit_cg_file_scope_asm(KitCg*, KitSlice asm_source);
   1484 
   1485 /* ============================================================
   1486  * Data Definitions
   1487  * ============================================================ */
   1488 
   1489 typedef enum KitCgDataDefFlag {
   1490   KIT_CG_DATADEF_NONE = 0,
   1491   KIT_CG_DATADEF_RETAIN = 1u << 0,
   1492   KIT_CG_DATADEF_MERGE = 1u << 1,
   1493   KIT_CG_DATADEF_STRINGS = 1u << 2,
   1494   KIT_CG_DATADEF_READONLY = 1u << 3,
   1495   KIT_CG_DATADEF_ZERO_FILL = 1u << 4,
   1496   /* Static storage with function/block scope for source backends. Native
   1497    * object backends may still emit ordinary private data. */
   1498   KIT_CG_DATADEF_FUNCTION_LOCAL = 1u << 5,
   1499 } KitCgDataDefFlag;
   1500 
   1501 typedef struct KitCgDataDefAttrs {
   1502   KitSym section;   /* 0 = target default for the symbol */
   1503   uint32_t align;   /* 0 = natural */
   1504   uint32_t entsize; /* 0 = target default; used by merge/string data */
   1505   uint32_t flags;   /* KitCgDataDefFlag */
   1506 } KitCgDataDefAttrs;
   1507 
   1508 /* data_begin defines storage for an already-declared object symbol.
   1509  * data_common defines tentative/common zero-initialized storage when the
   1510  * target format supports it.
   1511  *
   1512  * Data definitions may be emitted while a function body is open. The current
   1513  * function remains open across data_begin/data_end so frontends can define
   1514  * block-scope statics and computed-goto dispatch tables that need function
   1515  * label context. */
   1516 KIT_API void kit_cg_data_begin(KitCg*, KitCgSym sym, KitCgDataDefAttrs attrs);
   1517 KIT_API void kit_cg_data_common(KitCg*, KitCgSym sym, uint64_t size,
   1518                                 uint32_t align);
   1519 KIT_API void kit_cg_data_end(KitCg*);
   1520 
   1521 /* Appends to the currently open data definition. */
   1522 KIT_API void kit_cg_data_align(KitCg*, uint32_t align);
   1523 KIT_API void kit_cg_data_pad(KitCg*, uint64_t size, uint8_t value);
   1524 KIT_API void kit_cg_data_int(KitCg*, uint64_t value, KitCgTypeId type);
   1525 KIT_API void kit_cg_data_float(KitCg*, double value, KitCgTypeId type);
   1526 KIT_API void kit_cg_data_bytes(KitCg*, const uint8_t* data, size_t len);
   1527 KIT_API void kit_cg_data_zero(KitCg*, uint64_t size);
   1528 
   1529 /* Relocatable data expressions. These describe the value encoded in the data
   1530  * stream; they do not request a lowering strategy such as GOT, PLT, TLVP, or
   1531  * a TLS access model. width is the encoded field width in bytes. address_space
   1532  * is the pointer address space of address constants; use 0 for the target data
   1533  * address space. */
   1534 KIT_API void kit_cg_data_addr(KitCg*, KitCgSym target, int64_t addend,
   1535                               uint32_t width, uint32_t address_space);
   1536 /* Encodes a function-local label address for direct-threaded dispatch tables.
   1537  * The target label must have been created by kit_cg_label_new; it does not
   1538  * need to be placed yet, and the containing function must still be open so the
   1539  * label-address object can be tied to that function's label namespace. This
   1540  * supports the normal direct-threaded lowering: declare a dispatch-table
   1541  * symbol, begin the function, create labels, emit the table as data while the
   1542  * function is open, then resume code emission. The resulting value is an opaque
   1543  * label-address pointer: it may be loaded, stored, compared for equality,
   1544  * selected from tables, and consumed by kit_cg_computed_goto in the label's
   1545  * defining function. It must not be called, dereferenced as data, or used by
   1546  * another function's computed goto. */
   1547 KIT_API void kit_cg_data_label_addr(KitCg*, KitCgLabel target, int64_t addend,
   1548                                     uint32_t width, uint32_t address_space);
   1549 KIT_API void kit_cg_data_pcrel(KitCg*, KitCgSym target, int64_t addend,
   1550                                uint32_t width);
   1551 KIT_API void kit_cg_data_symdiff(KitCg*, KitCgSym lhs, KitCgSym rhs,
   1552                                  int64_t addend, uint32_t width);
   1553 
   1554 /* ============================================================
   1555  * Static Inline Convenience Operations
   1556  * ============================================================ */
   1557 
   1558 static inline void kit_cg_push_bytes(KitCg* cg, const uint8_t* data, size_t len,
   1559                                      KitCgTypeId pointee_type) {
   1560   KitCgSym sym = kit_cg_const_data(cg, data, len, 0, pointee_type);
   1561   kit_cg_push_symbol_addr(cg, sym, 0);
   1562 }
   1563 
   1564 static inline void kit_cg_call_default(KitCg* cg, uint32_t nargs,
   1565                                        KitCgTypeId fn_type) {
   1566   KitCgCallAttrs attrs;
   1567   attrs.tail = KIT_CG_TAIL_DEFAULT;
   1568   attrs.flags = 0;
   1569   attrs.inline_policy = KIT_CG_INLINE_DEFAULT;
   1570   kit_cg_call(cg, nargs, fn_type, attrs);
   1571 }
   1572 
   1573 static inline void kit_cg_call_symbol_default(KitCg* cg, KitCgSym sym,
   1574                                               uint32_t nargs) {
   1575   KitCgCallAttrs attrs;
   1576   attrs.tail = KIT_CG_TAIL_DEFAULT;
   1577   attrs.flags = 0;
   1578   attrs.inline_policy = KIT_CG_INLINE_DEFAULT;
   1579   kit_cg_call_symbol(cg, sym, nargs, attrs);
   1580 }
   1581 
   1582 static inline void kit_cg_tail_call(KitCg* cg, uint32_t nargs,
   1583                                     KitCgTypeId fn_type) {
   1584   KitCgCallAttrs attrs;
   1585   attrs.tail = KIT_CG_TAIL_ALLOWED;
   1586   attrs.flags = 0;
   1587   attrs.inline_policy = KIT_CG_INLINE_DEFAULT;
   1588   kit_cg_call(cg, nargs, fn_type, attrs);
   1589 }
   1590 
   1591 static inline void kit_cg_tail_call_symbol(KitCg* cg, KitCgSym sym,
   1592                                            uint32_t nargs) {
   1593   KitCgCallAttrs attrs;
   1594   attrs.tail = KIT_CG_TAIL_ALLOWED;
   1595   attrs.flags = 0;
   1596   attrs.inline_policy = KIT_CG_INLINE_DEFAULT;
   1597   kit_cg_call_symbol(cg, sym, nargs, attrs);
   1598 }
   1599 
   1600 static inline void kit_cg_musttail_call(KitCg* cg, uint32_t nargs,
   1601                                         KitCgTypeId fn_type) {
   1602   KitCgCallAttrs attrs;
   1603   attrs.tail = KIT_CG_TAIL_MUST;
   1604   attrs.flags = 0;
   1605   attrs.inline_policy = KIT_CG_INLINE_DEFAULT;
   1606   kit_cg_call(cg, nargs, fn_type, attrs);
   1607 }
   1608 
   1609 static inline void kit_cg_musttail_call_symbol(KitCg* cg, KitCgSym sym,
   1610                                                uint32_t nargs) {
   1611   KitCgCallAttrs attrs;
   1612   attrs.tail = KIT_CG_TAIL_MUST;
   1613   attrs.flags = 0;
   1614   attrs.inline_policy = KIT_CG_INLINE_DEFAULT;
   1615   kit_cg_call_symbol(cg, sym, nargs, attrs);
   1616 }
   1617 
   1618 /* Read the scalar value of a local. Stack: [] -> [value]. */
   1619 static inline void kit_cg_local_read(KitCg* cg, KitCgLocal local,
   1620                                      KitCgMemAccess access) {
   1621   kit_cg_push_local(cg, local);
   1622   kit_cg_load(cg, access);
   1623 }
   1624 
   1625 /* Write the scalar value on TOS into a local. Stack: [value] -> []. */
   1626 static inline void kit_cg_local_write(KitCg* cg, KitCgLocal local,
   1627                                       KitCgMemAccess access) {
   1628   kit_cg_push_local(cg, local); /* [value, lv] */
   1629   kit_cg_swap(cg);              /* [lv, value] */
   1630   kit_cg_store(cg, access);
   1631 }
   1632 
   1633 /* Increment/decrement an lvalue in place. Stack: [lv] -> [result].
   1634  * post=1 pushes the old value; post=0 pushes the new value.
   1635  * op is KIT_CG_INT_ADD or KIT_CG_INT_SUB. ty is the promoted integer type
   1636  * of the lvalue. */
   1637 static inline void kit_cg_inc_dec(KitCg* cg, KitCgIntBinOp op, int post,
   1638                                   KitCgTypeId ty, KitCgMemAccess access) {
   1639   kit_cg_dup(cg);          /* [lv, lv] */
   1640   kit_cg_load(cg, access); /* [lv, old] */
   1641   if (post) {
   1642     kit_cg_dup(cg);              /* [lv, old, old] */
   1643     kit_cg_push_int(cg, 1, ty);  /* [lv, old, old, 1] */
   1644     kit_cg_int_binop(cg, op, 0); /* [lv, old, new] */
   1645     kit_cg_rot3(cg);             /* [old, new, lv] */
   1646     kit_cg_swap(cg);             /* [old, lv, new] */
   1647     kit_cg_store(cg, access);    /* [old] */
   1648   } else {
   1649     kit_cg_push_int(cg, 1, ty);  /* [lv, old, 1] */
   1650     kit_cg_int_binop(cg, op, 0); /* [lv, new] */
   1651     kit_cg_dup(cg);              /* [lv, new, new] */
   1652     kit_cg_rot3(cg);             /* [new, new, lv] */
   1653     kit_cg_swap(cg);             /* [new, lv, new] */
   1654     kit_cg_store(cg, access);    /* [new] */
   1655   }
   1656 }
   1657 
   1658 /* `if (cond) then [else else_body]` lowering via two nested forward blocks.
   1659  *
   1660  *   outer = block_begin             (break = "end of if")
   1661  *     inner = block_begin           (break = "else entry point")
   1662  *       break_false(inner)          ; pop cond, skip then-body if false
   1663  *       then-body
   1664  *     if_else: break(outer); end inner
   1665  *     [optional else-body]
   1666  *   if_end: end outer
   1667  *
   1668  * Frontends must call kit_cg_if_else exactly once after the then-body
   1669  * (even if there is no else clause — the call closes the inner block so
   1670  * if_end can close only the outer). Using structured scopes means backends
   1671  * that already lower BLOCK + break natively (every native arch and the Wasm
   1672  * target) handle `if`/`if-else` without a CFG-to-structured pass. */
   1673 typedef struct KitCgIf {
   1674   KitCgScope outer;
   1675   KitCgScope inner;
   1676 } KitCgIf;
   1677 
   1678 static inline KitCgIf kit_cg_if_begin(KitCg* cg) {
   1679   KitCgIf it;
   1680   it.outer = kit_cg_block_begin(cg);
   1681   it.inner = kit_cg_block_begin(cg);
   1682   kit_cg_break_false(cg, it.inner);
   1683   return it;
   1684 }
   1685 
   1686 static inline void kit_cg_if_else(KitCg* cg, KitCgIf it) {
   1687   kit_cg_break(cg, it.outer);
   1688   kit_cg_scope_end(cg, it.inner);
   1689 }
   1690 
   1691 static inline void kit_cg_if_end(KitCg* cg, KitCgIf it) {
   1692   kit_cg_scope_end(cg, it.outer);
   1693 }
   1694 
   1695 /* Extract bits [lo, lo+width) from TOS as an unsigned value.
   1696  * Stack: [value] -> [field]. ty is the integer type of the value.
   1697  * width < 64 masks with (1<<width)-1; width == 64 keeps all bits. */
   1698 static inline void kit_cg_bitget(KitCg* cg, KitCgTypeId ty, uint32_t lo,
   1699                                  uint32_t width) {
   1700   if (lo > 0) {
   1701     kit_cg_push_int(cg, lo, ty);
   1702     kit_cg_int_binop(cg, KIT_CG_INT_LSHR, 0);
   1703   }
   1704   if (width < 64) {
   1705     kit_cg_push_int(cg, (1ULL << width) - 1, ty);
   1706     kit_cg_int_binop(cg, KIT_CG_INT_AND, 0);
   1707   }
   1708 }
   1709 
   1710 /* Insert the low width bits of src into dst at bit position lo.
   1711  * Stack: [dst, src] -> [result]. ty is the integer type.
   1712  * result = (dst & ~field_mask) | ((src << lo) & field_mask)
   1713  * where field_mask = ((1<<width)-1) << lo. width < 64; for width == 64 use
   1714  * bitget + shift + or directly. */
   1715 static inline void kit_cg_bitset(KitCg* cg, KitCgTypeId ty, uint32_t lo,
   1716                                  uint32_t width) {
   1717   uint64_t field_mask = ((1ULL << width) - 1) << lo;
   1718   uint64_t clear_mask = ~field_mask;
   1719   kit_cg_swap(cg); /* [src, dst] */
   1720   kit_cg_dup(cg);  /* [src, dst, dst] */
   1721   kit_cg_push_int(cg, clear_mask, ty);
   1722   kit_cg_int_binop(cg, KIT_CG_INT_AND, 0); /* [src, dst, dst_cleared] */
   1723   kit_cg_rot3(cg);                         /* [dst, dst_cleared, src] */
   1724   if (lo > 0) {
   1725     kit_cg_push_int(cg, lo, ty);
   1726     kit_cg_int_binop(cg, KIT_CG_INT_SHL, 0); /* [dst, dst_cleared, src<<lo] */
   1727   }
   1728   kit_cg_push_int(cg, field_mask, ty);
   1729   kit_cg_int_binop(cg, KIT_CG_INT_AND, 0); /* [dst, dst_cleared, bits] */
   1730   kit_cg_rot3(cg);                         /* [dst_cleared, bits, dst] */
   1731   kit_cg_drop(cg);                         /* [dst_cleared, bits] */
   1732   kit_cg_int_binop(cg, KIT_CG_INT_OR, 0);  /* [result] */
   1733 }
   1734 
   1735 #endif