type.c (31101B)
1 #include "arch/arch.h" 2 #include "cg/internal.h" 3 #include "obj/obj.h" 4 5 typedef enum CgApiTypeKind { 6 CG_API_TYPE_PTR, 7 CG_API_TYPE_ARRAY, 8 CG_API_TYPE_ALIAS, 9 CG_API_TYPE_RECORD, 10 CG_API_TYPE_ENUM, 11 CG_API_TYPE_FUNC, 12 } CgApiTypeKind; 13 14 typedef struct CgApiType { 15 CgType cg; 16 KitCgTypeId base; 17 KitSym name; 18 u32 count; 19 u32 flags; 20 u32 address_space; 21 u64 array_count; 22 const KitCgField* fields; 23 const KitCgEnumValue* values; 24 const KitCgFuncParam* params; 25 KitCgFuncResult result; /* result.type == KIT_CG_TYPE_NONE == void */ 26 KitCgCallConv call_conv; 27 u8 kind; 28 u8 abi_variadic; 29 u8 pad[2]; 30 } CgApiType; 31 32 SEGVEC_DEFINE(CgApiTypes, CgApiType, CG_API_TYPE_SEG_SHIFT); 33 34 typedef struct CgApiState { 35 Heap* heap; 36 CgApiTypes types; 37 CgType builtins[KIT_CG_BUILTIN_COUNT]; 38 u8 builtins_init; 39 u8 pad[3]; 40 } CgApiState; 41 42 static KitCgTypeId type_id_from_tuple(u32 seg, u32 index) { 43 return (KitCgTypeId)((seg << CG_API_TYPE_SEG_SHIFT) | 44 (index & CG_API_TYPE_SEG_MASK)); 45 } 46 47 KitCgTypeId builtin_id(KitCgBuiltinType t) { 48 return type_id_from_tuple(CG_API_TYPE_BUILTIN_SEG, (u32)t); 49 } 50 51 static int decode_user_id(KitCgTypeId id, u32* index_out) { 52 u32 seg = id >> CG_API_TYPE_SEG_SHIFT; 53 u32 off = id & CG_API_TYPE_SEG_MASK; 54 if (seg < CG_API_TYPE_USER_SEG_BIAS) return 0; 55 *index_out = 56 ((seg - CG_API_TYPE_USER_SEG_BIAS) << CG_API_TYPE_SEG_SHIFT) | off; 57 return 1; 58 } 59 60 static KitCgTypeId user_id_from_index(u32 index) { 61 u32 raw_seg = index >> CG_API_TYPE_SEG_SHIFT; 62 u32 off = index & CG_API_TYPE_SEG_MASK; 63 u32 seg_limit = UINT32_MAX >> CG_API_TYPE_SEG_SHIFT; 64 if (raw_seg > seg_limit - CG_API_TYPE_USER_SEG_BIAS) { 65 return KIT_CG_TYPE_NONE; 66 } 67 return type_id_from_tuple(raw_seg + CG_API_TYPE_USER_SEG_BIAS, off); 68 } 69 70 static KitCgTypeId type_id_for_user_index(u32 index) { 71 return user_id_from_index(index); 72 } 73 74 static u64 cg_align_to(u64 n, u32 align) { 75 u64 a = align ? (u64)align : 1u; 76 return ((n + a - 1u) / a) * a; 77 } 78 79 static void builtin_cg_type_init(Compiler* c, CgType* out, KitCgBuiltinType t) { 80 memset(out, 0, sizeof(*out)); 81 switch (t) { 82 case KIT_CG_BUILTIN_VOID: 83 out->kind = KIT_CG_TYPE_VOID; 84 out->align = 1; 85 break; 86 case KIT_CG_BUILTIN_BOOL: 87 out->kind = KIT_CG_TYPE_BOOL; 88 out->size = 1; 89 out->align = 1; 90 out->integer.width = 8; 91 break; 92 case KIT_CG_BUILTIN_I8: 93 out->kind = KIT_CG_TYPE_INT; 94 out->size = 1; 95 out->align = 1; 96 out->integer.width = 8; 97 break; 98 case KIT_CG_BUILTIN_I16: 99 out->kind = KIT_CG_TYPE_INT; 100 out->size = 2; 101 out->align = 2; 102 out->integer.width = 16; 103 break; 104 case KIT_CG_BUILTIN_I32: 105 out->kind = KIT_CG_TYPE_INT; 106 out->size = 4; 107 out->align = 4; 108 out->integer.width = 32; 109 break; 110 case KIT_CG_BUILTIN_I64: 111 out->kind = KIT_CG_TYPE_INT; 112 out->size = 8; 113 out->align = 8; 114 out->integer.width = 64; 115 break; 116 case KIT_CG_BUILTIN_I128: 117 out->kind = KIT_CG_TYPE_INT; 118 out->size = 16; 119 out->align = 16; 120 out->integer.width = 128; 121 break; 122 case KIT_CG_BUILTIN_F32: 123 out->kind = KIT_CG_TYPE_FLOAT; 124 out->size = 4; 125 out->align = 4; 126 out->fp.width = 32; 127 break; 128 case KIT_CG_BUILTIN_F64: 129 out->kind = KIT_CG_TYPE_FLOAT; 130 out->size = 8; 131 out->align = 8; 132 out->fp.width = 64; 133 break; 134 case KIT_CG_BUILTIN_F128: 135 out->kind = KIT_CG_TYPE_FLOAT; 136 out->size = 16; 137 out->align = 16; 138 out->fp.width = 128; 139 break; 140 case KIT_CG_BUILTIN_VARARG_STATE: { 141 ABITypeInfo info = abi_va_list_info(c->abi); 142 out->kind = KIT_CG_TYPE_VARARG_STATE; 143 out->size = info.size; 144 out->align = info.align ? info.align : 1; 145 break; 146 } 147 case KIT_CG_BUILTIN_COUNT: 148 break; 149 } 150 } 151 152 static void cg_api_init_builtins(Compiler* c, CgApiState* s) { 153 if (s->builtins_init) return; 154 for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) { 155 builtin_cg_type_init(c, &s->builtins[i], (KitCgBuiltinType)i); 156 } 157 s->builtins_init = 1; 158 } 159 160 static CgApiState* cg_api_get(Compiler* c) { 161 Heap* h; 162 CgApiState* s; 163 if (!c) return NULL; 164 if (c->cg_api) return (CgApiState*)c->cg_api; 165 h = (Heap*)c->ctx->heap; 166 s = (CgApiState*)h->alloc(h, sizeof(*s), _Alignof(CgApiState)); 167 if (!s) return NULL; 168 memset(s, 0, sizeof(*s)); 169 s->heap = h; 170 CgApiTypes_init(&s->types, h); 171 c->cg_api = s; 172 c->cg_api_free = cg_api_fini; 173 cg_api_init_builtins(c, s); 174 return s; 175 } 176 177 static CgApiType* api_type_from_id(Compiler* c, KitCgTypeId id); 178 179 const CgType* cg_type_get(Compiler* c, KitCgTypeId id) { 180 u32 seg; 181 u32 off; 182 CgApiState* s; 183 CgApiType* e; 184 if (!c || id == KIT_CG_TYPE_NONE) return NULL; 185 seg = id >> CG_API_TYPE_SEG_SHIFT; 186 off = id & CG_API_TYPE_SEG_MASK; 187 if (seg == CG_API_TYPE_BUILTIN_SEG) { 188 if (off >= KIT_CG_BUILTIN_COUNT) return NULL; 189 s = cg_api_get(c); 190 if (!s) return NULL; 191 cg_api_init_builtins(c, s); 192 return &s->builtins[off]; 193 } 194 e = api_type_from_id(c, id); 195 return e ? &e->cg : NULL; 196 } 197 198 uint64_t cg_type_size(Compiler* c, KitCgTypeId id) { 199 const CgType* ty = cg_type_get(c, id); 200 return ty ? ty->size : 0; 201 } 202 203 uint32_t cg_type_align(Compiler* c, KitCgTypeId id) { 204 const CgType* ty = cg_type_get(c, id); 205 return ty ? ty->align : 0; 206 } 207 208 int cg_type_is_int(Compiler* c, KitCgTypeId id) { 209 const CgType* ty = cg_type_get(c, id); 210 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) { 211 return cg_type_is_int(c, ty->alias.base); 212 } 213 return ty && (ty->kind == KIT_CG_TYPE_INT || ty->kind == KIT_CG_TYPE_BOOL || 214 ty->kind == KIT_CG_TYPE_ENUM); 215 } 216 217 int cg_type_is_float(Compiler* c, KitCgTypeId id) { 218 const CgType* ty = cg_type_get(c, id); 219 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) { 220 return cg_type_is_float(c, ty->alias.base); 221 } 222 return ty && ty->kind == KIT_CG_TYPE_FLOAT; 223 } 224 225 int cg_type_is_ptr(Compiler* c, KitCgTypeId id) { 226 const CgType* ty = cg_type_get(c, id); 227 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) { 228 return cg_type_is_ptr(c, ty->alias.base); 229 } 230 return ty && ty->kind == KIT_CG_TYPE_PTR; 231 } 232 233 int cg_type_is_record(Compiler* c, KitCgTypeId id) { 234 const CgType* ty = cg_type_get(c, id); 235 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) { 236 return cg_type_is_record(c, ty->alias.base); 237 } 238 return ty && ty->kind == KIT_CG_TYPE_RECORD; 239 } 240 241 int cg_type_is_void(Compiler* c, KitCgTypeId id) { 242 const CgType* ty = cg_type_get(c, id); 243 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) 244 return cg_type_is_void(c, ty->alias.base); 245 return ty && ty->kind == KIT_CG_TYPE_VOID; 246 } 247 248 int cg_type_is_aggregate(Compiler* c, KitCgTypeId id) { 249 return cg_type_is_record(c, id); 250 } 251 252 KitCgTypeId cg_type_ptr_to(Compiler* c, KitCgTypeId pointee) { 253 return kit_cg_type_ptr(c, pointee, 0); 254 } 255 256 KitCgTypeId cg_type_pointee(Compiler* c, KitCgTypeId id) { 257 const CgType* ty = cg_type_get(c, id); 258 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) 259 return cg_type_pointee(c, ty->alias.base); 260 return ty && ty->kind == KIT_CG_TYPE_PTR ? ty->ptr.pointee : KIT_CG_TYPE_NONE; 261 } 262 263 KitCgTypeId cg_type_func_ret_id(Compiler* c, KitCgTypeId id) { 264 const CgType* ty = cg_type_get(c, id); 265 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) 266 return cg_type_func_ret_id(c, ty->alias.base); 267 if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return KIT_CG_TYPE_NONE; 268 return ty->func.result.type ? ty->func.result.type 269 : builtin_id(KIT_CG_BUILTIN_VOID); 270 } 271 272 KitCgTypeId cg_func_ret_type(const CgType* fnty) { 273 return fnty->func.result.type ? fnty->func.result.type 274 : builtin_id(KIT_CG_BUILTIN_VOID); 275 } 276 277 KitCgTypeId cg_type_func_result_id(Compiler* c, KitCgTypeId id) { 278 const CgType* ty = cg_type_get(c, id); 279 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) 280 return cg_type_func_result_id(c, ty->alias.base); 281 if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return KIT_CG_TYPE_NONE; 282 return ty->func.result.type; 283 } 284 285 KitCgTypeId cg_type_func_param_id(Compiler* c, KitCgTypeId id, u32 index) { 286 const CgType* ty = cg_type_get(c, id); 287 if (ty && ty->kind == KIT_CG_TYPE_ALIAS) 288 return cg_type_func_param_id(c, ty->alias.base, index); 289 if (!ty || ty->kind != KIT_CG_TYPE_FUNC || index >= ty->func.nparams) 290 return KIT_CG_TYPE_NONE; 291 return ty->func.params[index].type; 292 } 293 294 static CgApiType* type_alloc(Compiler* c, KitCgTypeId* id_out) { 295 CgApiState* s = cg_api_get(c); 296 CgApiType* e; 297 u32 index; 298 if (!s) return NULL; 299 e = CgApiTypes_push(&s->types, &index); 300 if (!e) return NULL; 301 *id_out = user_id_from_index(index); 302 if (*id_out == KIT_CG_TYPE_NONE) return NULL; 303 return e; 304 } 305 306 static KitCgTypeId find_ptr_type_id(Compiler* c, KitCgTypeId pointee, 307 u32 address_space) { 308 CgApiState* s; 309 u32 n; 310 if (!c || !c->cg_api) return KIT_CG_TYPE_NONE; 311 s = (CgApiState*)c->cg_api; 312 n = CgApiTypes_count(&s->types); 313 for (u32 i = 0; i < n; ++i) { 314 CgApiType* e = CgApiTypes_at(&s->types, i); 315 if (e && e->kind == CG_API_TYPE_PTR && e->base == pointee && 316 e->address_space == address_space) 317 return type_id_for_user_index(i); 318 } 319 return KIT_CG_TYPE_NONE; 320 } 321 322 static KitCgTypeId find_array_type_id(Compiler* c, KitCgTypeId elem, 323 u64 count) { 324 CgApiState* s; 325 u32 n; 326 if (!c || !c->cg_api) return KIT_CG_TYPE_NONE; 327 s = (CgApiState*)c->cg_api; 328 n = CgApiTypes_count(&s->types); 329 for (u32 i = 0; i < n; ++i) { 330 CgApiType* e = CgApiTypes_at(&s->types, i); 331 if (e && e->kind == CG_API_TYPE_ARRAY && e->base == elem && 332 e->array_count == count) 333 return type_id_for_user_index(i); 334 } 335 return KIT_CG_TYPE_NONE; 336 } 337 338 static int cg_params_eq(const KitCgFuncParam* a, const KitCgFuncParam* b, 339 u32 n) { 340 for (u32 i = 0; i < n; ++i) 341 if (a[i].type != b[i].type || 342 memcmp(&a[i].attrs, &b[i].attrs, sizeof(a[i].attrs)) != 0) { 343 return 0; 344 } 345 return 1; 346 } 347 348 static int cg_result_eq(const KitCgFuncResult* a, const KitCgFuncResult* b) { 349 return a->type == b->type && 350 memcmp(&a->attrs, &b->attrs, sizeof(a->attrs)) == 0; 351 } 352 353 static KitCgTypeId find_func_type_id(Compiler* c, KitCgFuncSig sig) { 354 CgApiState* s; 355 u32 n; 356 if (!c || !c->cg_api) return KIT_CG_TYPE_NONE; 357 s = (CgApiState*)c->cg_api; 358 n = CgApiTypes_count(&s->types); 359 for (u32 i = 0; i < n; ++i) { 360 CgApiType* e = CgApiTypes_at(&s->types, i); 361 if (!e || e->kind != CG_API_TYPE_FUNC) continue; 362 if (e->count != sig.nparams) continue; 363 if (e->abi_variadic != (sig.abi_variadic != 0)) continue; 364 if (e->call_conv != sig.call_conv) continue; 365 if (!cg_result_eq(&e->result, &sig.result)) continue; 366 if (sig.nparams && !cg_params_eq(e->params, sig.params, sig.nparams)) { 367 continue; 368 } 369 return type_id_for_user_index(i); 370 } 371 return KIT_CG_TYPE_NONE; 372 } 373 374 static CgApiType* api_type_from_id(Compiler* c, KitCgTypeId id) { 375 u32 index; 376 CgApiState* s; 377 CgApiType* e; 378 if (!c || id == KIT_CG_TYPE_NONE) return NULL; 379 if ((id >> CG_API_TYPE_SEG_SHIFT) == CG_API_TYPE_BUILTIN_SEG) return NULL; 380 if (!decode_user_id(id, &index)) return NULL; 381 s = (CgApiState*)c->cg_api; 382 if (!s) return NULL; 383 e = CgApiTypes_at(&s->types, index); 384 return e; 385 } 386 387 KitCgTypeId resolve_type(Compiler* c, KitCgTypeId id) { 388 return cg_type_get(c, id) ? id : KIT_CG_TYPE_NONE; 389 } 390 391 KitCgTypeId api_unalias_type(Compiler* c, KitCgTypeId id) { 392 const CgType* ty = cg_type_get(c, id); 393 while (ty && ty->kind == KIT_CG_TYPE_ALIAS) { 394 id = ty->alias.base; 395 ty = cg_type_get(c, id); 396 } 397 return ty ? id : KIT_CG_TYPE_NONE; 398 } 399 400 static KitCgFuncParam* copy_cg_params(Compiler* c, const KitCgFuncParam* src, 401 u32 n) { 402 KitCgFuncParam* dst; 403 if (!n) return NULL; 404 if (!src) return NULL; 405 dst = arena_array(&c->global->arena, KitCgFuncParam, n); 406 if (!dst) return NULL; 407 memcpy(dst, src, sizeof(*dst) * n); 408 return dst; 409 } 410 411 static CgTypeField* copy_cg_fields(Compiler* c, const KitCgField* src, u32 n) { 412 CgTypeField* dst; 413 if (!n) return NULL; 414 if (!src) return NULL; 415 dst = arena_array(&c->global->arena, CgTypeField, n); 416 if (!dst) return NULL; 417 memset(dst, 0, sizeof(*dst) * n); 418 for (u32 i = 0; i < n; ++i) { 419 dst[i].name = src[i].name; 420 dst[i].type = src[i].type; 421 dst[i].align_override = src[i].align_override; 422 dst[i].max_align = src[i].max_align; 423 dst[i].flags = src[i].flags; 424 dst[i].bit_width = src[i].bit_width; 425 dst[i].bit_signed = src[i].bit_signed != 0; 426 } 427 return dst; 428 } 429 430 static int cg_type_layout_record(Compiler* c, CgType* cg) { 431 u32 max_align = 1; 432 u64 size = 0; 433 if (!c || !cg || cg->kind != KIT_CG_TYPE_RECORD) return 0; 434 if (cg->record.nfields && !cg->record.fields) return 0; 435 if (cg->record.is_union) { 436 for (u32 i = 0; i < cg->record.nfields; ++i) { 437 CgTypeField* f = &cg->record.fields[i]; 438 u64 fsize = cg_type_size(c, f->type); 439 u32 falign = cg_type_align(c, f->type); 440 if (!falign) return 0; 441 if (f->max_align && falign > f->max_align) falign = f->max_align; 442 if (f->align_override == 1u) { 443 falign = 1; 444 } else if (f->align_override > falign) { 445 falign = f->align_override; 446 } 447 if (falign > max_align) max_align = falign; 448 if ((f->flags & KIT_CG_FIELD_BITFIELD) != 0) { 449 f->offset = 0; 450 f->bit_offset = 0; 451 f->bit_storage_size = (u32)fsize; 452 if (f->bit_width == 0) continue; 453 } 454 if (fsize > size) size = fsize; 455 f->offset = 0; 456 } 457 } else { 458 u64 off = 0; 459 int active_bitfield_unit = 0; 460 u64 unit_off = 0; 461 u32 unit_bits = 0; 462 u32 unit_size = 0; 463 u32 next_bit = 0; 464 for (u32 i = 0; i < cg->record.nfields; ++i) { 465 CgTypeField* f = &cg->record.fields[i]; 466 u64 fsize = cg_type_size(c, f->type); 467 u32 falign = cg_type_align(c, f->type); 468 if (!falign) return 0; 469 if (f->max_align && falign > f->max_align) falign = f->max_align; 470 if (f->align_override == 1u) { 471 falign = 1; 472 } else if (f->align_override > falign) { 473 falign = f->align_override; 474 } 475 if (falign > max_align) max_align = falign; 476 if ((f->flags & KIT_CG_FIELD_BITFIELD) != 0) { 477 if (fsize > UINT32_MAX / 8u) return 0; 478 if (f->bit_width == 0) { 479 if (active_bitfield_unit) off = unit_off + unit_size; 480 off = cg_align_to(off, falign); 481 f->offset = off; 482 f->bit_offset = 0; 483 f->bit_storage_size = (u32)fsize; 484 active_bitfield_unit = 0; 485 next_bit = 0; 486 continue; 487 } 488 if (f->bit_width > fsize * 8u) return 0; 489 if (!active_bitfield_unit || unit_size != (u32)fsize || 490 next_bit + f->bit_width > unit_bits) { 491 if (active_bitfield_unit) off = unit_off + unit_size; 492 off = cg_align_to(off, falign); 493 unit_off = off; 494 unit_size = (u32)fsize; 495 unit_bits = unit_size * 8u; 496 next_bit = 0; 497 active_bitfield_unit = 1; 498 } 499 f->offset = unit_off; 500 f->bit_offset = (u16)next_bit; 501 f->bit_storage_size = unit_size; 502 next_bit += f->bit_width; 503 off = unit_off + unit_size; 504 continue; 505 } 506 active_bitfield_unit = 0; 507 off = cg_align_to(off, falign); 508 f->offset = off; 509 off += fsize; 510 } 511 size = off; 512 } 513 if (cg->record.align_override > max_align) { 514 max_align = cg->record.align_override; 515 } 516 cg->align = max_align; 517 cg->size = cg_align_to(size, max_align); 518 return 1; 519 } 520 521 static int cg_type_set_ptr(Compiler* c, CgApiType* e, KitCgTypeId pointee, 522 u32 address_space) { 523 u32 ptr_size; 524 u32 ptr_align; 525 if (!cg_type_get(c, pointee)) return 0; 526 memset(&e->cg, 0, sizeof(e->cg)); 527 ptr_size = c->target.ptr_size ? c->target.ptr_size : 8; 528 ptr_align = c->target.ptr_align ? c->target.ptr_align : ptr_size; 529 e->cg.kind = KIT_CG_TYPE_PTR; 530 e->cg.size = ptr_size; 531 e->cg.align = ptr_align; 532 e->cg.ptr.pointee = pointee; 533 e->cg.ptr.address_space = address_space; 534 return 1; 535 } 536 537 static int cg_type_set_array(Compiler* c, CgApiType* e, KitCgTypeId elem, 538 u64 count) { 539 const CgType* ety = cg_type_get(c, elem); 540 if (!ety) return 0; 541 memset(&e->cg, 0, sizeof(e->cg)); 542 e->cg.kind = KIT_CG_TYPE_ARRAY; 543 e->cg.size = ety->size * count; 544 e->cg.align = ety->align; 545 e->cg.array.elem = elem; 546 e->cg.array.count = count; 547 return 1; 548 } 549 550 static int cg_type_set_alias(Compiler* c, CgApiType* e, KitSym name, 551 KitCgTypeId base) { 552 const CgType* bty = cg_type_get(c, base); 553 if (!bty) return 0; 554 memset(&e->cg, 0, sizeof(e->cg)); 555 e->cg.kind = KIT_CG_TYPE_ALIAS; 556 e->cg.size = bty->size; 557 e->cg.align = bty->align; 558 e->cg.alias.name = name; 559 e->cg.alias.base = base; 560 return 1; 561 } 562 563 static int cg_type_set_record(Compiler* c, CgApiType* e, KitSym tag, 564 const KitCgField* fields, u32 nfields, 565 int is_union, u32 align_override, u32 flags) { 566 CgTypeField* copied = copy_cg_fields(c, fields, nfields); 567 if (nfields && !copied) return 0; 568 memset(&e->cg, 0, sizeof(e->cg)); 569 e->cg.kind = KIT_CG_TYPE_RECORD; 570 e->cg.record.tag = tag; 571 e->cg.record.fields = copied; 572 e->cg.record.nfields = nfields; 573 e->cg.record.is_union = is_union != 0; 574 e->cg.record.align_override = align_override; 575 e->cg.record.flags = flags; 576 return cg_type_layout_record(c, &e->cg); 577 } 578 579 static int cg_type_set_enum(Compiler* c, CgApiType* e, KitSym tag, 580 KitCgTypeId base, KitCgEnumValue* values, 581 u32 nvalues) { 582 const CgType* bty; 583 if (base == KIT_CG_TYPE_NONE) base = builtin_id(KIT_CG_BUILTIN_I32); 584 bty = cg_type_get(c, base); 585 if (!bty || 586 !(bty->kind == KIT_CG_TYPE_INT || bty->kind == KIT_CG_TYPE_BOOL)) { 587 return 0; 588 } 589 memset(&e->cg, 0, sizeof(e->cg)); 590 e->cg.kind = KIT_CG_TYPE_ENUM; 591 e->cg.size = bty->size; 592 e->cg.align = bty->align; 593 e->cg.enum_.tag = tag; 594 e->cg.enum_.base = base; 595 e->cg.enum_.values = values; 596 e->cg.enum_.nvalues = nvalues; 597 return 1; 598 } 599 600 static int cg_type_set_func(Compiler* c, CgApiType* e, KitCgFuncSig sig, 601 KitCgFuncParam* params) { 602 if (sig.result.type && !cg_type_get(c, sig.result.type)) return 0; 603 for (u32 i = 0; i < sig.nparams; ++i) { 604 if (!cg_type_get(c, sig.params[i].type)) return 0; 605 } 606 memset(&e->cg, 0, sizeof(e->cg)); 607 e->cg.kind = KIT_CG_TYPE_FUNC; 608 e->cg.size = 1; 609 e->cg.align = 1; 610 e->cg.func.result = sig.result; 611 e->cg.func.params = params; 612 e->cg.func.nparams = sig.nparams; 613 e->cg.func.call_conv = sig.call_conv; 614 e->cg.func.abi_variadic = sig.abi_variadic != 0; 615 return 1; 616 } 617 618 KitCgBuiltinTypes kit_cg_builtin_types(KitCompiler* c) { 619 KitCgBuiltinTypes out; 620 (void)c; 621 memset(&out, 0, sizeof(out)); 622 for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) { 623 out.id[i] = builtin_id((KitCgBuiltinType)i); 624 } 625 return out; 626 } 627 628 KitCgTypeId kit_cg_type_ptr(KitCompiler* c, KitCgTypeId pointee, 629 uint32_t address_space) { 630 KitCgTypeId id; 631 CgApiType* e; 632 if (!cg_type_get(c, pointee)) return KIT_CG_TYPE_NONE; 633 id = find_ptr_type_id(c, pointee, address_space); 634 if (id != KIT_CG_TYPE_NONE) return id; 635 e = type_alloc(c, &id); 636 if (!e) return KIT_CG_TYPE_NONE; 637 e->base = pointee; 638 e->address_space = address_space; 639 e->kind = CG_API_TYPE_PTR; 640 if (!cg_type_set_ptr(c, e, pointee, address_space)) { 641 return KIT_CG_TYPE_NONE; 642 } 643 return id; 644 } 645 646 KitCgTypeId kit_cg_type_array(KitCompiler* c, KitCgTypeId elem, 647 uint64_t count) { 648 KitCgTypeId id; 649 CgApiType* e; 650 if (!cg_type_get(c, elem) || count > UINT32_MAX) return KIT_CG_TYPE_NONE; 651 id = find_array_type_id(c, elem, count); 652 if (id != KIT_CG_TYPE_NONE) return id; 653 e = type_alloc(c, &id); 654 if (!e) return KIT_CG_TYPE_NONE; 655 e->base = elem; 656 e->array_count = count; 657 e->kind = CG_API_TYPE_ARRAY; 658 if (!cg_type_set_array(c, e, elem, count)) { 659 return KIT_CG_TYPE_NONE; 660 } 661 return id; 662 } 663 664 KitCgTypeId kit_cg_type_alias(KitCompiler* c, KitSym name, KitCgTypeId base) { 665 KitCgTypeId id; 666 CgApiType* e; 667 if (!cg_type_get(c, base)) return KIT_CG_TYPE_NONE; 668 e = type_alloc(c, &id); 669 if (!e) return KIT_CG_TYPE_NONE; 670 e->base = base; 671 e->name = name; 672 e->kind = CG_API_TYPE_ALIAS; 673 return cg_type_set_alias(c, e, name, base) ? id : KIT_CG_TYPE_NONE; 674 } 675 676 KitCgTypeId kit_cg_type_record(KitCompiler* c, KitSym tag, 677 const KitCgField* fields, uint32_t nfields) { 678 KitCgRecordDesc desc; 679 memset(&desc, 0, sizeof desc); 680 desc.tag = tag; 681 desc.fields = fields; 682 desc.nfields = nfields; 683 return kit_cg_type_record_ex(c, &desc); 684 } 685 686 KitCgTypeId kit_cg_type_record_ex(KitCompiler* c, const KitCgRecordDesc* desc) { 687 KitCgTypeId id; 688 CgApiType* e; 689 KitCgField* copied = NULL; 690 if (!c || !desc || (desc->nfields && !desc->fields) || 691 desc->nfields > UINT16_MAX) { 692 return KIT_CG_TYPE_NONE; 693 } 694 if (desc->nfields) { 695 copied = arena_array(&c->global->arena, KitCgField, desc->nfields); 696 if (!copied) return KIT_CG_TYPE_NONE; 697 } 698 699 for (u32 i = 0; i < desc->nfields; ++i) { 700 if (!cg_type_get(c, desc->fields[i].type)) return KIT_CG_TYPE_NONE; 701 copied[i] = desc->fields[i]; 702 } 703 e = type_alloc(c, &id); 704 if (!e) return KIT_CG_TYPE_NONE; 705 e->name = desc->tag; 706 e->count = desc->nfields; 707 e->fields = copied; 708 e->kind = CG_API_TYPE_RECORD; 709 if (!cg_type_set_record(c, e, desc->tag, desc->fields, desc->nfields, 710 desc->is_union, desc->align_override, 0)) { 711 return KIT_CG_TYPE_NONE; 712 } 713 return id; 714 } 715 716 KitCgTypeId kit_cg_type_enum(KitCompiler* c, KitSym tag, KitCgTypeId base, 717 const KitCgEnumValue* values, uint32_t nvalues) { 718 KitCgEnumValue* copied = NULL; 719 KitCgTypeId id; 720 CgApiType* e; 721 if (!c || (nvalues && !values)) return KIT_CG_TYPE_NONE; 722 if (base == KIT_CG_TYPE_NONE) base = builtin_id(KIT_CG_BUILTIN_I32); 723 if (!cg_type_is_int(c, base)) return KIT_CG_TYPE_NONE; 724 if (nvalues) { 725 copied = arena_array(&c->global->arena, KitCgEnumValue, nvalues); 726 if (!copied) return KIT_CG_TYPE_NONE; 727 memcpy(copied, values, sizeof(*copied) * nvalues); 728 } 729 e = type_alloc(c, &id); 730 if (!e) return KIT_CG_TYPE_NONE; 731 e->base = base; 732 e->name = tag; 733 e->count = nvalues; 734 e->values = copied; 735 e->kind = CG_API_TYPE_ENUM; 736 if (!cg_type_set_enum(c, e, tag, base, copied, nvalues)) { 737 return KIT_CG_TYPE_NONE; 738 } 739 return id; 740 } 741 742 KitCgTypeId kit_cg_type_func(KitCompiler* c, KitCgFuncSig sig) { 743 KitCgFuncParam* copied = NULL; 744 KitCgTypeId id; 745 CgApiType* e; 746 if (!c || (sig.nparams && !sig.params) || sig.nparams > UINT16_MAX) { 747 return KIT_CG_TYPE_NONE; 748 } 749 if (sig.result.type && !cg_type_get(c, sig.result.type)) 750 return KIT_CG_TYPE_NONE; 751 id = find_func_type_id(c, sig); 752 if (id != KIT_CG_TYPE_NONE) return id; 753 if (sig.nparams) { 754 copied = copy_cg_params(c, sig.params, sig.nparams); 755 if (!copied) return KIT_CG_TYPE_NONE; 756 for (u32 i = 0; i < sig.nparams; ++i) { 757 if (!cg_type_get(c, sig.params[i].type)) return KIT_CG_TYPE_NONE; 758 } 759 } 760 e = type_alloc(c, &id); 761 if (!e) return KIT_CG_TYPE_NONE; 762 e->count = sig.nparams; 763 e->params = copied; 764 e->result = sig.result; 765 e->call_conv = sig.call_conv; 766 e->abi_variadic = sig.abi_variadic != 0; 767 e->kind = CG_API_TYPE_FUNC; 768 if (!cg_type_set_func(c, e, sig, copied)) { 769 return KIT_CG_TYPE_NONE; 770 } 771 return id; 772 } 773 774 uint64_t kit_cg_type_size(KitCompiler* c, KitCgTypeId id) { 775 return cg_type_size(c, id); 776 } 777 778 uint32_t kit_cg_type_align(KitCompiler* c, KitCgTypeId id) { 779 return cg_type_align(c, id); 780 } 781 782 KitCgTypeKind kit_cg_type_kind(KitCompiler* c, KitCgTypeId id) { 783 const CgType* ty = cg_type_get(c, id); 784 return ty ? ty->kind : KIT_CG_TYPE_VOID; 785 } 786 787 uint32_t kit_cg_type_int_width(KitCompiler* c, KitCgTypeId id) { 788 const CgType* ty = cg_type_get(c, id); 789 if (!ty) return 0; 790 if (ty->kind == KIT_CG_TYPE_INT || ty->kind == KIT_CG_TYPE_BOOL) { 791 return ty->integer.width; 792 } 793 if (ty->kind == KIT_CG_TYPE_ENUM) { 794 return (uint32_t)ty->size * 8u; 795 } 796 if (ty->kind == KIT_CG_TYPE_ALIAS) { 797 return kit_cg_type_int_width(c, ty->alias.base); 798 } 799 return 0; 800 } 801 802 uint32_t kit_cg_type_float_width(KitCompiler* c, KitCgTypeId id) { 803 const CgType* ty = cg_type_get(c, id); 804 if (!ty) return 0; 805 if (ty->kind == KIT_CG_TYPE_FLOAT) return ty->fp.width; 806 if (ty->kind == KIT_CG_TYPE_ALIAS) { 807 return kit_cg_type_float_width(c, ty->alias.base); 808 } 809 return 0; 810 } 811 812 KitCgTypeId kit_cg_type_ptr_pointee(KitCompiler* c, KitCgTypeId id) { 813 const CgType* ty = cg_type_get(c, id); 814 return (ty && ty->kind == KIT_CG_TYPE_PTR) ? ty->ptr.pointee 815 : KIT_CG_TYPE_NONE; 816 } 817 818 KitCgTypeId kit_cg_type_array_elem(KitCompiler* c, KitCgTypeId id) { 819 const CgType* ty = cg_type_get(c, id); 820 return (ty && ty->kind == KIT_CG_TYPE_ARRAY) ? ty->array.elem 821 : KIT_CG_TYPE_NONE; 822 } 823 824 uint32_t kit_cg_type_ptr_address_space(KitCompiler* c, KitCgTypeId id) { 825 const CgType* ty = cg_type_get(c, id); 826 return (ty && ty->kind == KIT_CG_TYPE_PTR) ? ty->ptr.address_space : 0u; 827 } 828 829 uint64_t kit_cg_type_array_count(KitCompiler* c, KitCgTypeId id) { 830 const CgType* ty = cg_type_get(c, id); 831 return (ty && ty->kind == KIT_CG_TYPE_ARRAY) ? ty->array.count : 0u; 832 } 833 834 KitCgFuncResult kit_cg_type_func_result(KitCompiler* c, KitCgTypeId id) { 835 const CgType* ty = cg_type_get(c, id); 836 KitCgFuncResult empty; 837 memset(&empty, 0, sizeof(empty)); 838 if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return empty; 839 return ty->func.result; 840 } 841 842 uint32_t kit_cg_type_func_nparams(KitCompiler* c, KitCgTypeId id) { 843 const CgType* ty = cg_type_get(c, id); 844 return (ty && ty->kind == KIT_CG_TYPE_FUNC) ? ty->func.nparams : 0; 845 } 846 847 KitCgFuncParam kit_cg_type_func_param(KitCompiler* c, KitCgTypeId id, 848 uint32_t index) { 849 const CgType* ty = cg_type_get(c, id); 850 KitCgFuncParam empty; 851 memset(&empty, 0, sizeof(empty)); 852 if (!ty || ty->kind != KIT_CG_TYPE_FUNC || index >= ty->func.nparams) { 853 return empty; 854 } 855 return ty->func.params[index]; 856 } 857 858 KitCgCallConv kit_cg_type_func_call_conv(KitCompiler* c, KitCgTypeId id) { 859 const CgType* ty = cg_type_get(c, id); 860 return (ty && ty->kind == KIT_CG_TYPE_FUNC) ? ty->func.call_conv 861 : KIT_CG_CC_TARGET_C; 862 } 863 864 int kit_cg_type_func_is_variadic(KitCompiler* c, KitCgTypeId id) { 865 const CgType* ty = cg_type_get(c, id); 866 return ty && ty->kind == KIT_CG_TYPE_FUNC && ty->func.abi_variadic; 867 } 868 869 uint32_t kit_cg_type_record_nfields(KitCompiler* c, KitCgTypeId id) { 870 const CgType* ty = cg_type_get(c, id); 871 return (ty && ty->kind == KIT_CG_TYPE_RECORD) ? ty->record.nfields : 0; 872 } 873 874 KitStatus kit_cg_type_record_field(KitCompiler* c, KitCgTypeId id, 875 uint32_t index, KitCgField* out, 876 uint64_t* offset_out) { 877 const CgType* ty = cg_type_get(c, id); 878 const CgTypeField* f; 879 if (!ty || ty->kind != KIT_CG_TYPE_RECORD || index >= ty->record.nfields) { 880 return KIT_NOT_FOUND; 881 } 882 f = &ty->record.fields[index]; 883 if (out) { 884 out->name = f->name; 885 out->type = f->type; 886 out->align_override = f->align_override; 887 out->max_align = f->max_align; 888 out->flags = f->flags; 889 out->bit_width = f->bit_width; 890 out->bit_offset = f->bit_offset; 891 out->bit_storage_size = f->bit_storage_size; 892 out->bit_signed = f->bit_signed; 893 } 894 if (offset_out) *offset_out = f->offset; 895 return KIT_OK; 896 } 897 898 int kit_cg_target_supports_call_conv(KitCompiler* c, KitCgCallConv cc) { 899 const ArchImpl* a; 900 if (!c) return 0; 901 /* TARGET_C is always available, including for arches with no codegen backend 902 * (x86_32/arm_32, where arch_for_compiler is NULL). */ 903 if (cc == KIT_CG_CC_TARGET_C) return 1; 904 a = arch_for_compiler(c); 905 if (!a || !a->supports_call_conv) return 0; 906 return a->supports_call_conv(c, cc); 907 } 908 909 int kit_cg_target_supports_symbol_feature(KitCompiler* c, 910 KitCgSymbolFeature feat) { 911 if (!c) return 0; 912 switch (feat) { 913 case KIT_CG_SYMFEAT_WEAK: 914 case KIT_CG_SYMFEAT_PROTECTED_VISIBILITY: 915 case KIT_CG_SYMFEAT_COMDAT: 916 case KIT_CG_SYMFEAT_COMMON: 917 return 1; 918 case KIT_CG_SYMFEAT_TLS_LOCAL_EXEC: 919 /* Local-exec is the only TLS model kit emits. Whether it is actually 920 * available still depends on the object format being able to represent a 921 * TLS access at all (ELF/Mach-O yes; COFF/Wasm no). */ 922 return obj_format_supports_symbol_feature(c, (int)feat); 923 case KIT_CG_SYMFEAT_TLS_INITIAL_EXEC: 924 case KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC: 925 case KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC: 926 /* kit has no initial-exec / local-dynamic / general-dynamic codegen and 927 * no dynamic-TLS runtime (__tls_get_addr), so it never emits these even 928 * where the object format could represent them. Report the truth so a 929 * caller can't request a dynamic model and silently get local-exec; the 930 * linker enforces the same contract (see link_require_local_tls). */ 931 return 0; 932 case KIT_CG_SYMFEAT_DLLIMPORT: 933 case KIT_CG_SYMFEAT_DLLEXPORT: 934 case KIT_CG_SYMFEAT_MERGE_SECTIONS: 935 case KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY: 936 return 0; 937 } 938 return 0; 939 } 940 941 KitCgVaListKind kit_cg_target_va_list_kind(const KitCompiler* c) { 942 ABIVaListInfo va; 943 if (!c) return KIT_CG_VALIST_OPAQUE; 944 va = abi_va_list_layout(c->abi); 945 switch ((ABIVaListKind)va.kind) { 946 case ABI_VA_LIST_OPAQUE: 947 return KIT_CG_VALIST_OPAQUE; 948 case ABI_VA_LIST_POINTER: 949 return KIT_CG_VALIST_POINTER; 950 case ABI_VA_LIST_AAPCS64: 951 return KIT_CG_VALIST_AAPCS64; 952 case ABI_VA_LIST_SYSV_X64: 953 return KIT_CG_VALIST_SYSV_X64; 954 } 955 return KIT_CG_VALIST_OPAQUE; 956 } 957 958 const char* kit_cg_target_c_label_prefix(const KitCompiler* c) { 959 return obj_format_c_label_prefix(c); 960 } 961 962 int kit_cg_target_supports_intrinsic(KitCompiler* c, KitCgIntrinsic intrin) { 963 const ArchImpl* a; 964 if (!c) return 0; 965 a = arch_for_compiler(c); 966 if (!a || !a->supports_intrinsic) return 0; 967 return a->supports_intrinsic(c, intrin); 968 } 969 970 uint64_t kit_cg_target_backend_features(KitCompiler* c) { 971 const ArchImpl* a; 972 if (!c) return 0; 973 a = arch_for_compiler(c); 974 /* Arches with no registered codegen backend (x86_32) fall back to the 975 * conservative strict-alignment baseline. */ 976 if (!a) return KIT_CG_BACKEND_STRICT_ALIGNMENT; 977 return a->backend_features; 978 } 979 980 void cg_api_fini(Compiler* c) { 981 CgApiState* s; 982 if (!c || !c->cg_api) return; 983 s = (CgApiState*)c->cg_api; 984 CgApiTypes_fini(&s->types); 985 s->heap->free(s->heap, s, sizeof(*s)); 986 c->cg_api = NULL; 987 c->cg_api_free = NULL; 988 } 989 990 /* ============================================================ 991 * KitCg: public codegen API implementation 992 * 993 * Drives CgTarget directly with its own value stack. 994 * ============================================================ */