local.c (4656B)
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 /* int||float||ptr, in one type decode instead of three. */ 14 return !(api_type_pred_bits(g->c, ty) & 15 (API_PRED_INT | API_PRED_FLOAT | API_PRED_PTR)); 16 } 17 18 KitCgLocal api_local_handle(u32 index) { 19 u32 raw = index + 1u; 20 if (!raw) return KIT_CG_LOCAL_NONE; 21 return raw; 22 } 23 24 int api_grow_locals(KitCg* g, u32 want) { 25 Heap* h = g->c->ctx->heap; 26 ApiSourceLocal* nb; 27 u32 cap; 28 if (g->locals_cap >= want) return 1; 29 cap = g->locals_cap ? g->locals_cap : 16u; 30 while (cap < want) cap *= 2u; 31 nb = 32 (ApiSourceLocal*)h->alloc(h, sizeof(*nb) * cap, _Alignof(ApiSourceLocal)); 33 if (!nb) return 0; 34 memset(nb, 0, sizeof(*nb) * cap); 35 if (g->locals) { 36 memcpy(nb, g->locals, sizeof(*nb) * g->nlocals); 37 h->free(h, g->locals, sizeof(*g->locals) * g->locals_cap); 38 } 39 g->locals = nb; 40 g->locals_cap = cap; 41 return 1; 42 } 43 44 ApiSourceLocal* api_local_from_handle(KitCg* g, KitCgLocal local) { 45 u32 index; 46 if (local == KIT_CG_LOCAL_NONE) return NULL; 47 index = local - 1u; 48 if (index >= g->nlocals) { 49 return NULL; 50 } 51 return &g->locals[index]; 52 } 53 54 CGLocal api_frame_local_storage(KitCg* g, const CGLocalDesc* d) { 55 return g->target->local(g->target, d); 56 } 57 58 KitCgLocal kit_cg_local(KitCg* g, KitCgTypeId type, KitCgLocalAttrs attrs) { 59 KitCgTypeId ty; 60 CGLocalDesc desc; 61 CGLocal storage; 62 ApiSourceLocal* rec; 63 KitCgLocal handle; 64 if (!g) return KIT_CG_LOCAL_NONE; 65 ty = resolve_type(g->c, type); 66 if (!ty) return KIT_CG_LOCAL_NONE; 67 handle = api_local_handle(g->nlocals); 68 if (handle == KIT_CG_LOCAL_NONE || !api_grow_locals(g, g->nlocals + 1u)) 69 return KIT_CG_LOCAL_NONE; 70 memset(&desc, 0, sizeof desc); 71 desc.type = ty; 72 desc.name = (Sym)attrs.name; 73 desc.loc = g->cur_loc; 74 desc.size = abi_cg_sizeof(g->c->abi, ty); 75 desc.align = attrs.align ? attrs.align : abi_cg_alignof(g->c->abi, ty); 76 if (api_local_requires_memory(g, ty, attrs)) 77 desc.flags |= CG_LOCAL_MEMORY_REQUIRED; 78 if (api_unevaluated(g)) { 79 storage = CG_LOCAL_NONE; 80 } else if (g->target->local) 81 storage = g->target->local(g->target, &desc); 82 else 83 storage = api_frame_local_storage(g, &desc); 84 rec = &g->locals[g->nlocals++]; 85 memset(rec, 0, sizeof *rec); 86 rec->type = ty; 87 rec->name = attrs.name; 88 rec->attrs = attrs; 89 rec->loc = g->cur_loc; 90 rec->desc = desc; 91 rec->storage = storage; 92 rec->param_index = 0; 93 rec->kind = API_SOURCE_LOCAL_AUTO; 94 return handle; 95 } 96 97 KitCgLocal kit_cg_param(KitCg* g, uint32_t index, KitCgTypeId type, 98 KitCgLocalAttrs attrs) { 99 KitCgTypeId ty; 100 CGParamDesc pd; 101 ApiSourceLocal* rec; 102 KitCgLocal handle; 103 CGLocal storage; 104 u32 size; 105 u32 align; 106 if (!g) return KIT_CG_LOCAL_NONE; 107 ty = resolve_type(g->c, type); 108 if (!ty) return KIT_CG_LOCAL_NONE; 109 if (index != g->nlocals) return KIT_CG_LOCAL_NONE; 110 handle = api_local_handle(g->nlocals); 111 if (handle == KIT_CG_LOCAL_NONE || !api_grow_locals(g, g->nlocals + 1u)) 112 return KIT_CG_LOCAL_NONE; 113 114 size = abi_cg_sizeof(g->c->abi, ty); 115 align = attrs.align ? attrs.align : abi_cg_alignof(g->c->abi, ty); 116 117 memset(&pd, 0, sizeof pd); 118 pd.index = index; 119 pd.name = (Sym)attrs.name; 120 pd.type = ty; 121 pd.size = size; 122 pd.align = align; 123 if (api_local_requires_memory(g, ty, attrs)) 124 pd.flags |= CG_LOCAL_MEMORY_REQUIRED; 125 pd.loc = g->cur_loc; 126 storage = 127 api_unevaluated(g) ? CG_LOCAL_NONE : g->target->param(g->target, &pd); 128 129 rec = &g->locals[g->nlocals++]; 130 memset(rec, 0, sizeof *rec); 131 rec->type = ty; 132 rec->name = attrs.name; 133 rec->attrs = attrs; 134 rec->loc = g->cur_loc; 135 memset(&rec->desc, 0, sizeof rec->desc); 136 rec->desc.type = ty; 137 rec->desc.name = (Sym)attrs.name; 138 rec->desc.loc = g->cur_loc; 139 rec->desc.size = size; 140 rec->desc.align = align; 141 rec->desc.flags = pd.flags; 142 rec->storage = storage; 143 rec->param_index = index; 144 rec->kind = API_SOURCE_LOCAL_PARAM; 145 return handle; 146 } 147 148 /* ============================================================ 149 * Push operations 150 * ============================================================ */