local.c (4500B)
1 #include "cg/internal.h" 2 3 int api_local_requires_memory(KitCg* g, KitCgTypeId ty, KitCgLocalAttrs attrs) { 4 u32 hidden_flags = KIT_CG_LOCAL_ARTIFICIAL | KIT_CG_LOCAL_OPTIMIZED_OUT | 5 KIT_CG_LOCAL_COMPILER_TEMP; 6 if (attrs.flags & KIT_CG_LOCAL_MEMORY_REQUIRED) return 1; 7 if (g && g->debug && attrs.name && (attrs.flags & hidden_flags) == 0) 8 return 1; 9 /* Aggregates (records, arrays), wide16 (f128/i128), split-lane wide8, vararg 10 * state, and any non-scalar type must live in memory. */ 11 if (api_is_wide16_scalar_type(g->c, ty)) return 1; 12 if (api_is_wide8_scalar_type(g->c, ty)) return 1; 13 return !(cg_type_is_int(g->c, ty) || cg_type_is_float(g->c, ty) || 14 cg_type_is_ptr(g->c, ty)); 15 } 16 17 KitCgLocal api_local_handle(u32 index) { 18 u32 raw = index + 1u; 19 if (!raw) return KIT_CG_LOCAL_NONE; 20 return raw; 21 } 22 23 int api_grow_locals(KitCg* g, u32 want) { 24 Heap* h = g->c->ctx->heap; 25 ApiSourceLocal* nb; 26 u32 cap; 27 if (g->locals_cap >= want) return 1; 28 cap = g->locals_cap ? g->locals_cap : 16u; 29 while (cap < want) cap *= 2u; 30 nb = 31 (ApiSourceLocal*)h->alloc(h, sizeof(*nb) * cap, _Alignof(ApiSourceLocal)); 32 if (!nb) return 0; 33 memset(nb, 0, sizeof(*nb) * cap); 34 if (g->locals) { 35 memcpy(nb, g->locals, sizeof(*nb) * g->nlocals); 36 h->free(h, g->locals, sizeof(*g->locals) * g->locals_cap); 37 } 38 g->locals = nb; 39 g->locals_cap = cap; 40 return 1; 41 } 42 43 ApiSourceLocal* api_local_from_handle(KitCg* g, KitCgLocal local) { 44 u32 index; 45 if (local == KIT_CG_LOCAL_NONE) return NULL; 46 index = local - 1u; 47 if (index >= g->nlocals) { 48 return NULL; 49 } 50 return &g->locals[index]; 51 } 52 53 CGLocal api_frame_local_storage(KitCg* g, const CGLocalDesc* d) { 54 return g->target->local(g->target, d); 55 } 56 57 KitCgLocal kit_cg_local(KitCg* g, KitCgTypeId type, KitCgLocalAttrs attrs) { 58 KitCgTypeId ty; 59 CGLocalDesc desc; 60 CGLocal storage; 61 ApiSourceLocal* rec; 62 KitCgLocal handle; 63 if (!g) return KIT_CG_LOCAL_NONE; 64 ty = resolve_type(g->c, type); 65 if (!ty) return KIT_CG_LOCAL_NONE; 66 handle = api_local_handle(g->nlocals); 67 if (handle == KIT_CG_LOCAL_NONE || !api_grow_locals(g, g->nlocals + 1u)) 68 return KIT_CG_LOCAL_NONE; 69 memset(&desc, 0, sizeof desc); 70 desc.type = ty; 71 desc.name = (Sym)attrs.name; 72 desc.loc = g->cur_loc; 73 desc.size = abi_cg_sizeof(g->c->abi, type); 74 desc.align = attrs.align ? attrs.align : abi_cg_alignof(g->c->abi, type); 75 if (api_local_requires_memory(g, ty, attrs)) 76 desc.flags |= CG_LOCAL_MEMORY_REQUIRED; 77 if (g->target->local) 78 storage = g->target->local(g->target, &desc); 79 else 80 storage = api_frame_local_storage(g, &desc); 81 rec = &g->locals[g->nlocals++]; 82 memset(rec, 0, sizeof *rec); 83 rec->type = ty; 84 rec->name = attrs.name; 85 rec->attrs = attrs; 86 rec->loc = g->cur_loc; 87 rec->desc = desc; 88 rec->storage = storage; 89 rec->param_index = 0; 90 rec->kind = API_SOURCE_LOCAL_AUTO; 91 return handle; 92 } 93 94 KitCgLocal kit_cg_param(KitCg* g, uint32_t index, KitCgTypeId type, 95 KitCgLocalAttrs attrs) { 96 KitCgTypeId ty; 97 CGParamDesc pd; 98 ApiSourceLocal* rec; 99 KitCgLocal handle; 100 CGLocal storage; 101 u32 size; 102 u32 align; 103 if (!g) return KIT_CG_LOCAL_NONE; 104 ty = resolve_type(g->c, type); 105 if (!ty) return KIT_CG_LOCAL_NONE; 106 if (index != g->nlocals) return KIT_CG_LOCAL_NONE; 107 handle = api_local_handle(g->nlocals); 108 if (handle == KIT_CG_LOCAL_NONE || !api_grow_locals(g, g->nlocals + 1u)) 109 return KIT_CG_LOCAL_NONE; 110 111 size = abi_cg_sizeof(g->c->abi, type); 112 align = attrs.align ? attrs.align : abi_cg_alignof(g->c->abi, type); 113 114 memset(&pd, 0, sizeof pd); 115 pd.index = index; 116 pd.name = (Sym)attrs.name; 117 pd.type = ty; 118 pd.size = size; 119 pd.align = align; 120 if (api_local_requires_memory(g, ty, attrs)) 121 pd.flags |= CG_LOCAL_MEMORY_REQUIRED; 122 pd.loc = g->cur_loc; 123 storage = g->target->param(g->target, &pd); 124 125 rec = &g->locals[g->nlocals++]; 126 memset(rec, 0, sizeof *rec); 127 rec->type = ty; 128 rec->name = attrs.name; 129 rec->attrs = attrs; 130 rec->loc = g->cur_loc; 131 memset(&rec->desc, 0, sizeof rec->desc); 132 rec->desc.type = ty; 133 rec->desc.name = (Sym)attrs.name; 134 rec->desc.loc = g->cur_loc; 135 rec->desc.size = size; 136 rec->desc.align = align; 137 rec->desc.flags = pd.flags; 138 rec->storage = storage; 139 rec->param_index = index; 140 rec->kind = API_SOURCE_LOCAL_PARAM; 141 return handle; 142 } 143 144 /* ============================================================ 145 * Push operations 146 * ============================================================ */