c_emit.h (10753B)
1 #ifndef KIT_C_TARGET_C_EMIT_H 2 #define KIT_C_TARGET_C_EMIT_H 3 4 /* C-source emission core. See doc/CBACKEND.md. 5 * 6 * This target is selected when CodeOptions.emit_c_source is set. It writes 7 * target-locked C source to CodeOptions.c_source_writer instead of object 8 * bytes. Operates with semantic temporary locals minted by CG. */ 9 10 #include <kit/core.h> 11 12 #include "cg/cgtarget.h" 13 #include "core/core.h" 14 15 typedef CGLocal CLocal; 16 17 /* Heap-backed growable byte buffer. Used for the per-function declaration 18 * and body buffers; CG needs decls at function top but doesn't surface them 19 * before body emission, so we accumulate both and flush at func_end. */ 20 typedef struct CBuf { 21 Heap* heap; 22 u8* data; 23 size_t len; 24 size_t cap; 25 } CBuf; 26 27 void cbuf_init(CBuf* b, Heap* h); 28 void cbuf_fini(CBuf* b); 29 void cbuf_reset(CBuf* b); 30 void cbuf_putc(CBuf* b, char c); 31 void cbuf_puts(CBuf* b, const char* s); 32 void cbuf_putn(CBuf* b, const char* s, size_t n); 33 void cbuf_put_i64(CBuf* b, i64 v); 34 void cbuf_put_u64(CBuf* b, u64 v); 35 36 typedef struct CLocalStaticLabelEntry { 37 Label label; 38 i64 addend; 39 u8 has_label; 40 u8 pad[3]; 41 } CLocalStaticLabelEntry; 42 43 typedef struct CTarget { 44 Compiler* c; 45 ObjBuilder* obj; 46 KitWriter* w; 47 48 /* TU prologue (e.g. #include <stdint.h>) emitted once, on first 49 * function or finalize, whichever first. */ 50 u8 prologue_emitted; 51 u8 finalized; 52 u8 pad[2]; 53 54 /* TU-wide forward declarations: one `RetT name(params);` line per function 55 * we've seen a definition or call for. Emitted just after the prologue so 56 * callers defined earlier in the TU still see the prototype, and calls to 57 * undefined-in-TU externs get a declaration too. */ 58 CBuf forwards; 59 /* Forward-decl dedup: which ObjSymIds have we already declared. Lazily 60 * grown bitmap indexed by ObjSymId. */ 61 u8* sym_forwarded; 62 u32 sym_forwarded_cap; 63 64 /* TU-wide typedefs (records, arrays, function pointers, opaque storage). 65 * Emitted between prologue and forwards. */ 66 CBuf typedefs; 67 /* TU-wide data definitions and extern data declarations. Emitted between 68 * forwards and function bodies so functions can reference data symbols and 69 * data initializers can reference function forward decls. Populated at 70 * finalize by walking the ObjBuilder's data sections. */ 71 CBuf data_defs; 72 /* Per-type id state: 0 = not seen, 1 = inflight, 2 = emitted. */ 73 u8* type_state; 74 u32 type_state_cap; 75 /* Tracks whether <stdarg.h> needs to be emitted in the prologue. Set when 76 * c_typename first encounters VARARG_STATE. Flushed lazily at finalize. */ 77 u8 need_stdarg; 78 u8 need_setjmp; 79 u8 pad2[2]; 80 81 /* Per-function buffers. Reset on func_end. */ 82 CBuf decls; 83 CBuf body; 84 85 /* Function-local static data consumed from CG's narrow source-backend data 86 * hook. These symbols are emitted inside the owning function and skipped by 87 * the TU-wide object-data walker. */ 88 ObjSymId* local_static_syms; 89 u32 local_static_nsyms; 90 u32 local_static_syms_cap; 91 92 CLocalStaticLabelEntry* local_static_entries; 93 u32 local_static_nentries; 94 u32 local_static_entries_cap; 95 ObjSymId local_static_sym; 96 KitCgTypeId local_static_type; 97 u64 local_static_count; 98 u64 local_static_offset; 99 u32 local_static_ptr_width; 100 u32 local_static_align; 101 u8 local_static_active; 102 u8 local_static_is_array; 103 u8 local_static_readonly; 104 u8 pad_local_static; 105 106 /* Per-function local-decl tracking: for each local id seen, mark whether we 107 * have already emitted a declaration into `decls`. Sized by local_cap. 108 * Grown lazily as new local ids appear. */ 109 u8* local_declared; 110 KitCgTypeId* local_type; /* declared type for each semantic local */ 111 u32 local_cap; 112 113 /* Splice bookmark: byte offset into body where the current function's body 114 * region starts (right after the open brace). func_end uses this to insert 115 * the per-function declarations between the signature and the body. */ 116 size_t fn_body_start; 117 118 const CGFuncDesc* cur_fn; 119 120 /* Most recent source line directive emitted into the current function body. 121 * Reset on func_begin; used by c_set_loc to avoid noisy duplicate #line 122 * directives. */ 123 SrcLoc emitted_loc; 124 u8 have_emitted_loc; 125 u8 pad_cur_loc[3]; 126 127 /* Label minting: ids 1..next_label. 0 is reserved as LABEL_NONE. */ 128 u32 next_label; 129 u32 next_local; 130 131 /* Stack of active scopes. CGScope handles are (scope_index + 1). */ 132 struct CScopeInfo* scopes; 133 u32 scopes_cap; 134 u32 nscopes; 135 136 /* Monotone counter for synthesizing unique temporary names within a 137 * function (e.g. bitcast scratch). Reset on func_begin. */ 138 u32 next_tmp; 139 140 /* Tracks whether the last emitted body statement was an unconditional 141 * terminator (`return`, `goto`, etc.) with no intervening label. When 142 * set, subsequent ret/jump/cmp_branch emissions are dropped — they're 143 * unreachable, and emitting them produces dead C that distracts from 144 * the live code. Reset on func_begin and label_place. */ 145 u8 last_was_terminator; 146 u8 pad3[3]; 147 } CTarget; 148 149 typedef struct CScopeInfo { 150 u8 kind; /* ScopeKind */ 151 /* Set when the C target emitted a `for (;;) { ... }` wrapper around 152 * this scope. Drives jump/cmp_branch's translation of break/continue 153 * labels into C `break;`/`continue;` and scope_end's `}`. */ 154 u8 structured; 155 u8 pad[2]; 156 Label break_label; 157 Label continue_label; 158 } CScopeInfo; 159 160 void c_emit_target_init(CTarget* t, Compiler* c, ObjBuilder* o, KitWriter* w); 161 CTarget* c_emit_target_new(Compiler* c, ObjBuilder* o, KitWriter* w); 162 163 void c_emit_prologue(CTarget* t); 164 /* Ensure local `r` (typed `type`) has been declared. */ 165 void c_ensure_local(CTarget* t, CLocal r, KitCgTypeId type); 166 /* Get a stable C identifier for local r. Writes into caller-supplied buf. */ 167 void c_local_name(CLocal r, char* out, size_t cap); 168 /* Write the C type for a CG int/float/ptr type to `b`. */ 169 void c_emit_type(CTarget* t, CBuf* b, KitCgTypeId type); 170 /* Write operand expression to body (e.g. "v3", "(int32_t)42"). Supports 171 * OPK_LOCAL / OPK_IMM / OPK_GLOBAL. INDIRECT is only valid in 172 * lvalue positions and is emitted via load/store/addr_of paths. */ 173 void c_emit_operand(CTarget* t, Operand op); 174 /* Like c_emit_operand but wraps in an explicit signed/unsigned cast of the 175 * operand's type width. For integer ops where signedness affects semantics 176 * (UDIV/UREM, SHR_U, unsigned compares). Falls back to c_emit_operand when 177 * the operand is not integer-typed. */ 178 void c_emit_operand_signed(CTarget* t, Operand op, int signed_); 179 180 /* Lookup the C linker name for an ObjSymId. Returns interned string. */ 181 const char* c_sym_name(CTarget* t, ObjSymId sym); 182 183 /* Emit a forward declaration for `sym` (of function type `fn_type`) into 184 * the TU forwards buffer if not already done. Idempotent per sym. */ 185 void c_ensure_forward_decl(CTarget* t, ObjSymId sym, KitCgTypeId fn_type); 186 187 /* Write `n` bytes to t->w; panic on error. */ 188 void c_writer_write(CTarget* t, const void* data, size_t n); 189 void c_writer_puts(CTarget* t, const char* s); 190 191 void c_emit_func_begin(CTarget*, const CGFuncDesc*); 192 void c_emit_func_end(CTarget*); 193 void c_emit_alias(CTarget*, ObjSymId, ObjSymId, KitCgTypeId); 194 /* Re-emit a file-scope `__asm__("...")` block verbatim at TU scope. */ 195 void c_emit_file_scope_asm(CTarget*, const char* src, size_t len); 196 void c_emit_ret(CTarget*, CGLocal value); 197 void c_emit_unreachable(CTarget*); 198 void c_emit_load_imm(CTarget*, Operand, i64); 199 void c_emit_load_const(CTarget*, Operand, ConstBytes); 200 void c_emit_copy(CTarget*, Operand, Operand); 201 void c_emit_binop(CTarget*, BinOp, Operand, Operand, Operand); 202 void c_emit_unop(CTarget*, UnOp, Operand, Operand); 203 void c_emit_cmp(CTarget*, CmpOp, Operand, Operand, Operand); 204 void c_emit_convert(CTarget*, ConvKind, Operand, Operand); 205 void c_emit_call(CTarget*, const CGCallDesc*); 206 const char* c_emit_tail_call_unrealizable_reason(CTarget*, const CGCallDesc*); 207 const char* c_emit_tail_call_unrealizable_reason_for(CTarget*, 208 const CGFuncDesc*, 209 const CGCallDesc*); 210 void c_emit_load(CTarget*, Operand, Operand, MemAccess); 211 void c_emit_store(CTarget*, Operand, Operand, MemAccess); 212 void c_emit_addr_of(CTarget*, Operand, Operand); 213 CGLocal c_emit_param(CTarget*, const CGParamDesc*); 214 CGLocal c_emit_local(CTarget*, const CGLocalDesc*); 215 void c_emit_param_bind(CTarget*, CGLocal, KitCgTypeId, u32); 216 void c_emit_local_addr(CTarget*, Operand, const CGLocalDesc*, CGLocal); 217 Label c_emit_label_new(CTarget*); 218 void c_emit_label_place(CTarget*, Label); 219 void c_emit_jump(CTarget*, Label); 220 void c_emit_cmp_branch(CTarget*, CmpOp, Operand, Operand, Label); 221 void c_emit_switch_(CTarget*, const CGSwitchDesc*); 222 void c_emit_indirect_branch(CTarget*, Operand, const Label*, u32); 223 void c_emit_load_label_addr(CTarget*, Operand, Label); 224 int c_emit_local_static_data_begin(CTarget*, const CGLocalStaticDataDesc*); 225 int c_emit_can_local_static_data(CTarget*, const CGLocalStaticDataDesc*); 226 void c_emit_local_static_data_write(CTarget*, const u8*, u64); 227 void c_emit_local_static_data_label_addr(CTarget*, Label, i64, u32, u32); 228 void c_emit_local_static_data_end(CTarget*); 229 CGScope c_emit_scope_begin(CTarget*, const CGScopeDesc*); 230 void c_emit_scope_end(CTarget*, CGScope); 231 void c_emit_break_to(CTarget*, CGScope); 232 void c_emit_continue_to(CTarget*, CGScope); 233 void c_emit_set_loc(CTarget*, SrcLoc); 234 void c_emit_finalize(CTarget*); 235 void c_emit_destroy(CTarget*); 236 void c_emit_intrinsic(CTarget*, IntrinKind, Operand*, u32, const Operand*, u32); 237 void c_emit_alloca(CTarget*, Operand, Operand, u32); 238 void c_emit_va_start(CTarget*, Operand); 239 void c_emit_va_arg(CTarget*, Operand, Operand, KitCgTypeId); 240 void c_emit_va_end(CTarget*, Operand); 241 void c_emit_va_copy(CTarget*, Operand, Operand); 242 void c_emit_copy_bytes(CTarget*, Operand, Operand, AggregateAccess); 243 void c_emit_set_bytes(CTarget*, Operand, Operand, AggregateAccess); 244 void c_emit_asm_block(CTarget*, const char*, const AsmConstraint*, u32, 245 Operand*, const AsmConstraint*, u32, const Operand*, 246 const Sym*, u32); 247 void c_emit_bitfield_load(CTarget*, Operand, Operand, BitFieldAccess); 248 void c_emit_bitfield_store(CTarget*, Operand, Operand, BitFieldAccess); 249 void c_emit_tls_addr_of(CTarget*, Operand, ObjSymId, i64); 250 void c_emit_atomic_load(CTarget*, Operand, Operand, MemAccess, KitCgMemOrder); 251 void c_emit_atomic_store(CTarget*, Operand, Operand, MemAccess, KitCgMemOrder); 252 void c_emit_atomic_rmw(CTarget*, KitCgAtomicOp, Operand, Operand, Operand, 253 MemAccess, KitCgMemOrder); 254 void c_emit_atomic_cas(CTarget*, Operand, Operand, Operand, Operand, Operand, 255 MemAccess, KitCgMemOrder, KitCgMemOrder); 256 void c_emit_fence(CTarget*, KitCgMemOrder); 257 258 #endif