cg_type_test.c (70466B)
1 #include <kit/cg.h> 2 #include <kit/compile.h> 3 #include <kit/core.h> 4 #include <kit/dwarf.h> 5 #include <kit/frontend.h> 6 #include <kit/object.h> 7 #include <kit/source.h> 8 #include <stdarg.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include "lib/kit_unit.h" 14 15 /* One shared test context replaces the per-file heap/diag/counter globals. 16 * EXPECT is aliased to CU_EXPECT so the call sites below are unchanged; the 17 * expected-panic helper uses g_u.suppress_fatal + g_u.last_diag. */ 18 static KitUnit g_u; 19 #define EXPECT(cond, ...) CU_EXPECT(&g_u, cond, __VA_ARGS__) 20 21 static KitObjBuilder* new_obj(KitCompiler* c) { 22 KitObjBuilder* ob = NULL; 23 if (kit_obj_builder_new(c, &ob) != KIT_OK) return NULL; 24 return ob; 25 } 26 27 static int open_emitted_obj(KitCompiler* c, KitObjBuilder* ob, 28 KitWriter** writer_out, KitObjFile** file_out) { 29 KitWriter* w = NULL; 30 KitObjFile* f = NULL; 31 KitSlice bytes; 32 size_t len = 0; 33 const KitContext* ctx; 34 35 if (!writer_out || !file_out) return 0; 36 *writer_out = NULL; 37 *file_out = NULL; 38 if (kit_writer_mem(&g_u.heap, &w) != KIT_OK || !w) return 0; 39 if (kit_obj_builder_emit(ob, w) != KIT_OK) { 40 kit_writer_close(w); 41 return 0; 42 } 43 bytes.data = kit_writer_mem_bytes(w, &len); 44 bytes.len = len; 45 ctx = kit_compiler_context(c); 46 if (kit_obj_open(ctx, KIT_SLICE_LIT("<cg-api-test>"), &bytes, &f) != KIT_OK) { 47 kit_writer_close(w); 48 return 0; 49 } 50 *writer_out = w; 51 *file_out = f; 52 return 1; 53 } 54 55 static void finish_cg(KitCg* cg, const char* tag) { 56 EXPECT(kit_cg_finish(cg, NULL) == KIT_OK, "%s cg finish failed", tag); 57 EXPECT(kit_cg_detach(cg) == KIT_OK, "%s cg detach failed", tag); 58 } 59 60 typedef struct PanicRunCtx { 61 void (*fn)(void*); 62 void* arg; 63 } PanicRunCtx; 64 65 static KitStatus run_expected_panic(KitCompiler* c, void* arg) { 66 PanicRunCtx* ctx = (PanicRunCtx*)arg; 67 (void)c; 68 ctx->fn(ctx->arg); 69 return KIT_OK; 70 } 71 72 static int expect_panic_contains(KitCompiler* c, void (*fn)(void*), void* arg, 73 const char* expected) { 74 PanicRunCtx ctx; 75 KitStatus st; 76 ctx.fn = fn; 77 ctx.arg = arg; 78 g_u.last_diag[0] = '\0'; 79 g_u.suppress_fatal++; 80 st = kit_frontend_run(c, run_expected_panic, &ctx); 81 g_u.suppress_fatal--; 82 return st == KIT_ERR && strstr(g_u.last_diag, expected) != NULL; 83 } 84 85 static void exercise_cg_handles(KitCompiler* c, KitCgTypeId i32_ty, 86 int opt_level) { 87 char name_buf[32]; 88 KitCodeOptions opts; 89 KitObjBuilder* ob; 90 KitCg* cg; 91 KitCgFuncParam param_desc; 92 KitCgFuncSig sig; 93 KitCgDecl decl; 94 KitCgSym sym; 95 KitCgLocalAttrs attrs; 96 KitCgLocal local; 97 KitCgLocal param; 98 KitCgMemAccess mem; 99 100 memset(&opts, 0, sizeof(opts)); 101 opts.opt_level = opt_level; 102 ob = new_obj(c); 103 EXPECT(ob != NULL, "obj builder allocation failed"); 104 if (!ob) return; 105 cg = NULL; 106 (void)kit_cg_new(c, &cg); 107 if (cg) (void)kit_cg_begin(cg, ob, &opts); 108 EXPECT(cg != NULL, "cg allocation failed"); 109 if (!cg) { 110 kit_obj_builder_free(ob); 111 return; 112 } 113 114 memset(¶m_desc, 0, sizeof(param_desc)); 115 param_desc.type = i32_ty; 116 memset(&sig, 0, sizeof(sig)); 117 KitCgFuncResult sig_result; 118 memset(&sig_result, 0, sizeof sig_result); 119 sig_result.type = i32_ty; 120 sig.result = sig_result; 121 sig.params = ¶m_desc; 122 sig.nparams = 1; 123 sig.call_conv = KIT_CG_CC_TARGET_C; 124 125 snprintf(name_buf, sizeof(name_buf), "cg_handles_o%d", opt_level); 126 memset(&decl, 0, sizeof(decl)); 127 decl.kind = KIT_CG_DECL_FUNC; 128 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name_buf)); 129 decl.display_name = decl.linkage_name; 130 decl.type = kit_cg_type_func(c, sig); 131 decl.sym.bind = KIT_SB_GLOBAL; 132 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 133 sym = kit_cg_decl(cg, decl); 134 EXPECT(sym != KIT_CG_SYM_NONE, "function decl failed"); 135 136 kit_cg_func_begin(cg, sym); 137 memset(&attrs, 0, sizeof(attrs)); 138 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p")); 139 param = kit_cg_param(cg, 0, i32_ty, attrs); 140 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 141 local = kit_cg_local(cg, i32_ty, attrs); 142 EXPECT(local != KIT_CG_LOCAL_NONE, "local handle is none"); 143 EXPECT(param != KIT_CG_LOCAL_NONE, "param handle is none"); 144 EXPECT((uint32_t)param == 1u, "first local id should be param"); 145 EXPECT((uint32_t)local == 2u, "local id should follow param"); 146 EXPECT((uint32_t)local != (uint32_t)param, "local and param handles collide"); 147 148 memset(&mem, 0, sizeof(mem)); 149 mem.type = i32_ty; 150 mem.align = kit_cg_type_align(c, i32_ty); 151 152 kit_cg_push_local(cg, local); 153 kit_cg_push_local_addr(cg, param); 154 kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the load */ 155 kit_cg_load(cg, mem); 156 kit_cg_store(cg, mem); 157 158 kit_cg_push_local_addr(cg, local); 159 kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the load */ 160 kit_cg_load(cg, mem); 161 kit_cg_ret(cg); 162 kit_cg_func_end(cg); 163 164 kit_cg_free(cg); 165 kit_obj_builder_free(ob); 166 } 167 168 static void exercise_cg_scalar_local(KitCompiler* c, KitCgTypeId i32_ty, 169 int opt_level) { 170 char name_buf[40]; 171 KitCodeOptions opts; 172 KitObjBuilder* ob; 173 KitCg* cg; 174 KitCgFuncSig sig; 175 KitCgDecl decl; 176 KitCgSym sym; 177 KitCgLocalAttrs attrs; 178 KitCgLocal local; 179 KitCgMemAccess mem; 180 181 memset(&opts, 0, sizeof opts); 182 opts.opt_level = opt_level; 183 ob = new_obj(c); 184 EXPECT(ob != NULL, "obj builder allocation failed"); 185 if (!ob) return; 186 cg = NULL; 187 (void)kit_cg_new(c, &cg); 188 if (cg) (void)kit_cg_begin(cg, ob, &opts); 189 EXPECT(cg != NULL, "cg allocation failed"); 190 if (!cg) { 191 kit_obj_builder_free(ob); 192 return; 193 } 194 195 memset(&sig, 0, sizeof sig); 196 KitCgFuncResult sig_result; 197 memset(&sig_result, 0, sizeof sig_result); 198 sig_result.type = i32_ty; 199 sig.result = sig_result; 200 sig.call_conv = KIT_CG_CC_TARGET_C; 201 202 snprintf(name_buf, sizeof name_buf, "cg_scalar_local_o%d", opt_level); 203 memset(&decl, 0, sizeof decl); 204 decl.kind = KIT_CG_DECL_FUNC; 205 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name_buf)); 206 decl.display_name = decl.linkage_name; 207 decl.type = kit_cg_type_func(c, sig); 208 decl.sym.bind = KIT_SB_GLOBAL; 209 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 210 sym = kit_cg_decl(cg, decl); 211 EXPECT(sym != KIT_CG_SYM_NONE, "scalar local decl failed"); 212 213 kit_cg_func_begin(cg, sym); 214 memset(&attrs, 0, sizeof attrs); 215 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 216 local = kit_cg_local(cg, i32_ty, attrs); 217 EXPECT(local != KIT_CG_LOCAL_NONE, "scalar local handle is none"); 218 219 memset(&mem, 0, sizeof mem); 220 mem.type = i32_ty; 221 mem.align = kit_cg_type_align(c, i32_ty); 222 223 kit_cg_push_local(cg, local); 224 kit_cg_push_int(cg, 40, i32_ty); 225 kit_cg_store(cg, mem); 226 kit_cg_push_local(cg, local); 227 kit_cg_load(cg, mem); 228 kit_cg_push_int(cg, 2, i32_ty); 229 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 230 kit_cg_ret(cg); 231 kit_cg_func_end(cg); 232 233 kit_cg_free(cg); 234 kit_obj_builder_free(ob); 235 } 236 237 static void exercise_cg_late_local_addr(KitCompiler* c, KitCgTypeId i32_ty, 238 int opt_level) { 239 char name_buf[40]; 240 KitCodeOptions opts; 241 KitObjBuilder* ob; 242 KitCg* cg; 243 KitCgFuncSig sig; 244 KitCgDecl decl; 245 KitCgSym sym; 246 KitCgLocalAttrs attrs; 247 KitCgLocal local; 248 KitCgMemAccess mem; 249 250 memset(&opts, 0, sizeof opts); 251 opts.opt_level = opt_level; 252 ob = new_obj(c); 253 EXPECT(ob != NULL, "obj builder allocation failed"); 254 if (!ob) return; 255 cg = NULL; 256 (void)kit_cg_new(c, &cg); 257 if (cg) (void)kit_cg_begin(cg, ob, &opts); 258 EXPECT(cg != NULL, "cg allocation failed"); 259 if (!cg) { 260 kit_obj_builder_free(ob); 261 return; 262 } 263 264 memset(&sig, 0, sizeof sig); 265 KitCgFuncResult sig_result; 266 memset(&sig_result, 0, sizeof sig_result); 267 sig_result.type = i32_ty; 268 sig.result = sig_result; 269 sig.call_conv = KIT_CG_CC_TARGET_C; 270 271 snprintf(name_buf, sizeof name_buf, "cg_late_local_addr_o%d", opt_level); 272 memset(&decl, 0, sizeof decl); 273 decl.kind = KIT_CG_DECL_FUNC; 274 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name_buf)); 275 decl.display_name = decl.linkage_name; 276 decl.type = kit_cg_type_func(c, sig); 277 decl.sym.bind = KIT_SB_GLOBAL; 278 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 279 sym = kit_cg_decl(cg, decl); 280 EXPECT(sym != KIT_CG_SYM_NONE, "late local addr decl failed"); 281 282 kit_cg_func_begin(cg, sym); 283 memset(&attrs, 0, sizeof attrs); 284 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 285 local = kit_cg_local(cg, i32_ty, attrs); 286 EXPECT(local != KIT_CG_LOCAL_NONE, "late addr local handle is none"); 287 288 memset(&mem, 0, sizeof mem); 289 mem.type = i32_ty; 290 mem.align = kit_cg_type_align(c, i32_ty); 291 292 kit_cg_push_local(cg, local); 293 kit_cg_push_int(cg, 41, i32_ty); 294 kit_cg_store(cg, mem); 295 kit_cg_push_local_addr(cg, local); 296 kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the load */ 297 kit_cg_load(cg, mem); 298 kit_cg_push_int(cg, 1, i32_ty); 299 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 300 kit_cg_ret(cg); 301 kit_cg_func_end(cg); 302 303 kit_cg_free(cg); 304 kit_obj_builder_free(ob); 305 } 306 307 static uint32_t text_size(KitCompiler* c, KitObjBuilder* ob) { 308 uint32_t total = 0; 309 KitWriter* w = NULL; 310 KitObjFile* f = NULL; 311 uint32_t n; 312 if (!open_emitted_obj(c, ob, &w, &f)) { 313 EXPECT(0, "failed to inspect emitted object"); 314 return 0; 315 } 316 n = kit_obj_nsections(f); 317 for (uint32_t i = 0; i < n; ++i) { 318 KitObjSecInfo sec; 319 if (kit_obj_section(f, i, &sec) != KIT_OK) continue; 320 if (sec.kind == KIT_SEC_TEXT) total += (uint32_t)sec.size; 321 } 322 kit_obj_free(f); 323 kit_writer_close(w); 324 return total; 325 } 326 327 static void exercise_cg_data_entsize(KitCompiler* c, KitCgTypeId i8_ty) { 328 static const uint8_t bytes[] = {'t', 'o', 'y', '\0'}; 329 KitCodeOptions opts; 330 KitObjBuilder* ob; 331 KitCg* cg; 332 KitCgDecl decl; 333 KitCgSym sym; 334 KitCgDataDefAttrs data_attrs; 335 KitCgTypeId array_ty; 336 int found = 0; 337 338 memset(&opts, 0, sizeof opts); 339 ob = new_obj(c); 340 EXPECT(ob != NULL, "entsize obj builder allocation failed"); 341 if (!ob) return; 342 cg = NULL; 343 (void)kit_cg_new(c, &cg); 344 if (cg) (void)kit_cg_begin(cg, ob, &opts); 345 EXPECT(cg != NULL, "entsize cg allocation failed"); 346 if (!cg) { 347 kit_obj_builder_free(ob); 348 return; 349 } 350 351 array_ty = kit_cg_type_array(c, i8_ty, sizeof bytes); 352 EXPECT(array_ty != KIT_CG_TYPE_NONE, "entsize array type failed"); 353 354 memset(&decl, 0, sizeof decl); 355 decl.kind = KIT_CG_DECL_OBJECT; 356 decl.linkage_name = kit_sym_intern(c, KIT_SLICE_LIT("cg_entsize_string")); 357 decl.display_name = decl.linkage_name; 358 decl.type = array_ty; 359 decl.sym.bind = KIT_SB_GLOBAL; 360 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 361 decl.as.object.flags = KIT_CG_OBJ_READONLY; 362 decl.as.object.align = 1; 363 sym = kit_cg_decl(cg, decl); 364 EXPECT(sym != KIT_CG_SYM_NONE, "entsize object decl failed"); 365 366 memset(&data_attrs, 0, sizeof data_attrs); 367 data_attrs.section = kit_sym_intern(c, KIT_SLICE_LIT(".rodata.kit.merge")); 368 data_attrs.align = 1; 369 data_attrs.entsize = 1; 370 data_attrs.flags = 371 KIT_CG_DATADEF_READONLY | KIT_CG_DATADEF_MERGE | KIT_CG_DATADEF_STRINGS; 372 kit_cg_data_begin(cg, sym, data_attrs); 373 kit_cg_data_bytes(cg, bytes, sizeof bytes); 374 kit_cg_data_end(cg); 375 finish_cg(cg, "entsize"); 376 kit_cg_free(cg); 377 378 { 379 KitWriter* w = NULL; 380 KitObjFile* f = NULL; 381 uint32_t n; 382 if (!open_emitted_obj(c, ob, &w, &f)) { 383 EXPECT(0, "failed to inspect entsize object"); 384 kit_obj_builder_free(ob); 385 return; 386 } 387 n = kit_obj_nsections(f); 388 for (uint32_t i = 0; i < n; ++i) { 389 KitObjSecInfo sec; 390 if (kit_obj_section(f, i, &sec) != KIT_OK) continue; 391 if ((sec.flags & (KIT_SF_MERGE | KIT_SF_STRINGS)) == 392 (KIT_SF_MERGE | KIT_SF_STRINGS)) { 393 found = 1; 394 EXPECT(sec.entsize == 1, 395 "merge string section entsize should be 1, got %u", sec.entsize); 396 } 397 } 398 kit_obj_free(f); 399 kit_writer_close(w); 400 } 401 EXPECT(found, "expected merge string data section"); 402 403 kit_obj_builder_free(ob); 404 } 405 406 static void exercise_cg_debug_global_object(KitCompiler* c, 407 KitCgTypeId i32_ty) { 408 KitCodeOptions opts; 409 KitObjBuilder* ob; 410 KitCg* cg; 411 KitCgDecl decl; 412 KitCgSym sym; 413 KitCgDataDefAttrs data_attrs; 414 KitSrcLoc loc; 415 uint32_t file_id = 0; 416 417 memset(&opts, 0, sizeof opts); 418 opts.debug_info = true; 419 ob = new_obj(c); 420 EXPECT(ob != NULL, "debug global obj builder allocation failed"); 421 if (!ob) return; 422 cg = NULL; 423 EXPECT(kit_cg_new(c, &cg) == KIT_OK && cg != NULL, 424 "debug global cg allocation failed"); 425 if (!cg) { 426 kit_obj_builder_free(ob); 427 return; 428 } 429 EXPECT(kit_cg_begin(cg, ob, &opts) == KIT_OK, "debug global cg begin failed"); 430 431 EXPECT(kit_source_add_memory(c, KIT_SLICE_LIT("cg_debug_global.c"), 432 &file_id) == KIT_OK, 433 "debug global source file add failed"); 434 loc.file_id = file_id; 435 loc.line = 7; 436 loc.col = 3; 437 kit_cg_set_loc(cg, loc); 438 439 memset(&decl, 0, sizeof decl); 440 decl.kind = KIT_CG_DECL_OBJECT; 441 decl.linkage_name = kit_sym_intern(c, KIT_SLICE_LIT("cg_dbg_global_link")); 442 decl.display_name = kit_sym_intern(c, KIT_SLICE_LIT("cg_dbg_global")); 443 decl.type = i32_ty; 444 decl.sym.bind = KIT_SB_GLOBAL; 445 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 446 sym = kit_cg_decl(cg, decl); 447 EXPECT(sym != KIT_CG_SYM_NONE, "debug global object decl failed"); 448 449 memset(&data_attrs, 0, sizeof data_attrs); 450 data_attrs.align = kit_cg_type_align(c, i32_ty); 451 kit_cg_data_begin(cg, sym, data_attrs); 452 kit_cg_data_int(cg, 42, i32_ty); 453 kit_cg_data_end(cg); 454 finish_cg(cg, "debug global"); 455 kit_cg_free(cg); 456 457 { 458 KitWriter* w = NULL; 459 KitObjFile* f = NULL; 460 KitDebugInfo* di = NULL; 461 KitDwarfVarLoc vloc; 462 KitDwarfVarIter* vit = NULL; 463 KitDwarfVar var; 464 int iter_found = 0; 465 466 if (!open_emitted_obj(c, ob, &w, &f)) { 467 EXPECT(0, "failed to inspect debug global object"); 468 kit_obj_builder_free(ob); 469 return; 470 } 471 EXPECT( 472 kit_dwarf_open(kit_compiler_context(c), f, &di) == KIT_OK && di != NULL, 473 "debug global dwarf open failed"); 474 if (di) { 475 EXPECT(kit_dwarf_var_at(di, 0, KIT_SLICE_LIT("cg_dbg_global"), &vloc) == 476 KIT_OK, 477 "debug global variable not found by display name"); 478 EXPECT(vloc.kind == KIT_DLOC_GLOBAL, 479 "debug global location kind %d, expected global", (int)vloc.kind); 480 EXPECT(vloc.byte_size == 4, "debug global byte size %u, expected 4", 481 vloc.byte_size); 482 EXPECT(vloc.type != NULL, "debug global type missing"); 483 484 EXPECT(kit_dwarf_vars_at_new(di, 0, KIT_DVRM_GLOBAL, &vit) == KIT_OK && 485 vit != NULL, 486 "debug global iterator allocation failed"); 487 if (vit) { 488 while (kit_dwarf_vars_at_next(vit, &var) == KIT_ITER_ITEM) { 489 if (kit_slice_eq_cstr(var.name, "cg_dbg_global") && 490 var.role == KIT_DVR_GLOBAL) { 491 iter_found = 1; 492 EXPECT(var.loc.kind == KIT_DLOC_GLOBAL, 493 "debug global iterator location kind %d", (int)var.loc.kind); 494 } 495 } 496 kit_dwarf_vars_at_free(vit); 497 } 498 EXPECT(iter_found, "debug global iterator did not report global"); 499 kit_dwarf_free(di); 500 } 501 kit_obj_free(f); 502 kit_writer_close(w); 503 } 504 505 kit_obj_builder_free(ob); 506 } 507 508 static KitCgSym begin_i32_func(KitCompiler* c, KitCg* cg, KitCgTypeId i32_ty, 509 const char* name) { 510 KitCgFuncSig sig; 511 KitCgDecl decl; 512 memset(&sig, 0, sizeof sig); 513 KitCgFuncResult sig_result; 514 memset(&sig_result, 0, sizeof sig_result); 515 sig_result.type = i32_ty; 516 sig.result = sig_result; 517 sig.call_conv = KIT_CG_CC_TARGET_C; 518 519 memset(&decl, 0, sizeof decl); 520 decl.kind = KIT_CG_DECL_FUNC; 521 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 522 decl.display_name = decl.linkage_name; 523 decl.type = kit_cg_type_func(c, sig); 524 decl.sym.bind = KIT_SB_GLOBAL; 525 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 526 return kit_cg_decl(cg, decl); 527 } 528 529 static void exercise_cg_literal_folds(KitCompiler* c, KitCgTypeId i32_ty) { 530 static const char* names[] = { 531 "cg_fold_add_o1", 532 "cg_fold_shift_or_o1", 533 "cg_fold_cmp_o1", 534 "cg_fold_unop_o1", 535 }; 536 KitCodeOptions opts; 537 KitObjBuilder* ob; 538 KitCg* cg; 539 540 memset(&opts, 0, sizeof opts); 541 opts.opt_level = 1; 542 ob = new_obj(c); 543 EXPECT(ob != NULL, "literal fold obj builder allocation failed"); 544 if (!ob) return; 545 cg = NULL; 546 (void)kit_cg_new(c, &cg); 547 if (cg) (void)kit_cg_begin(cg, ob, &opts); 548 EXPECT(cg != NULL, "literal fold cg allocation failed"); 549 if (!cg) { 550 kit_obj_builder_free(ob); 551 return; 552 } 553 554 for (uint32_t i = 0; i < 4; ++i) { 555 KitCgSym sym = begin_i32_func(c, cg, i32_ty, names[i]); 556 EXPECT(sym != KIT_CG_SYM_NONE, "literal fold decl failed"); 557 kit_cg_func_begin(cg, sym); 558 switch (i) { 559 case 0: 560 kit_cg_push_int(cg, 40, i32_ty); 561 kit_cg_push_int(cg, 2, i32_ty); 562 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 563 break; 564 case 1: 565 kit_cg_push_int(cg, 5, i32_ty); 566 kit_cg_push_int(cg, 3, i32_ty); 567 kit_cg_int_binop(cg, KIT_CG_INT_SHL, 0); 568 kit_cg_push_int(cg, 2, i32_ty); 569 kit_cg_int_binop(cg, KIT_CG_INT_OR, 0); 570 break; 571 case 2: 572 kit_cg_push_int(cg, 40, i32_ty); 573 kit_cg_push_int(cg, 2, i32_ty); 574 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 575 kit_cg_push_int(cg, 42, i32_ty); 576 kit_cg_int_cmp(cg, KIT_CG_INT_EQ); 577 break; 578 case 3: 579 kit_cg_push_int(cg, 41, i32_ty); 580 kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0); 581 kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0); 582 kit_cg_push_int(cg, 1, i32_ty); 583 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 584 break; 585 } 586 kit_cg_ret(cg); 587 kit_cg_func_end(cg); 588 } 589 590 finish_cg(cg, "literal fold"); 591 kit_cg_free(cg); 592 EXPECT(text_size(c, ob) <= 128, 593 "literal folds should avoid arithmetic materialization, text size=%u", 594 text_size(c, ob)); 595 kit_obj_builder_free(ob); 596 } 597 598 static uint32_t cg_emit_delayed_chain(KitCompiler* c, KitCgTypeId i32_ty, 599 const char* name) { 600 KitCodeOptions opts; 601 KitObjBuilder* ob; 602 KitCg* cg; 603 KitCgFuncParam param_desc; 604 KitCgFuncSig sig; 605 KitCgDecl decl; 606 KitCgSym sym; 607 KitCgLocalAttrs attrs; 608 KitCgLocal param; 609 KitCgMemAccess mem; 610 uint32_t size; 611 612 memset(&opts, 0, sizeof opts); 613 opts.opt_level = 1; 614 ob = new_obj(c); 615 EXPECT(ob != NULL, "delayed chain obj builder allocation failed"); 616 if (!ob) return 0; 617 cg = NULL; 618 (void)kit_cg_new(c, &cg); 619 if (cg) (void)kit_cg_begin(cg, ob, &opts); 620 EXPECT(cg != NULL, "delayed chain cg allocation failed"); 621 if (!cg) { 622 kit_obj_builder_free(ob); 623 return 0; 624 } 625 626 memset(¶m_desc, 0, sizeof param_desc); 627 param_desc.type = i32_ty; 628 memset(&sig, 0, sizeof sig); 629 KitCgFuncResult sig_result; 630 memset(&sig_result, 0, sizeof sig_result); 631 sig_result.type = i32_ty; 632 sig.result = sig_result; 633 sig.params = ¶m_desc; 634 sig.nparams = 1; 635 sig.call_conv = KIT_CG_CC_TARGET_C; 636 637 memset(&decl, 0, sizeof decl); 638 decl.kind = KIT_CG_DECL_FUNC; 639 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 640 decl.display_name = decl.linkage_name; 641 decl.type = kit_cg_type_func(c, sig); 642 decl.sym.bind = KIT_SB_GLOBAL; 643 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 644 sym = kit_cg_decl(cg, decl); 645 EXPECT(sym != KIT_CG_SYM_NONE, "delayed chain decl failed"); 646 647 kit_cg_func_begin(cg, sym); 648 memset(&attrs, 0, sizeof attrs); 649 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p")); 650 param = kit_cg_param(cg, 0, i32_ty, attrs); 651 EXPECT(param != KIT_CG_LOCAL_NONE, "delayed chain param failed"); 652 memset(&mem, 0, sizeof mem); 653 mem.type = i32_ty; 654 mem.align = kit_cg_type_align(c, i32_ty); 655 kit_cg_push_local(cg, param); 656 kit_cg_load(cg, mem); 657 kit_cg_push_int(cg, 40, i32_ty); 658 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 659 kit_cg_push_int(cg, 2, i32_ty); 660 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 661 kit_cg_ret(cg); 662 kit_cg_func_end(cg); 663 664 finish_cg(cg, "delayed chain"); 665 kit_cg_free(cg); 666 size = text_size(c, ob); 667 kit_obj_builder_free(ob); 668 return size; 669 } 670 671 static uint32_t cg_emit_unary_chain(KitCompiler* c, KitCgTypeId i32_ty, 672 const char* name) { 673 KitCodeOptions opts; 674 KitObjBuilder* ob; 675 KitCg* cg; 676 KitCgFuncParam param_desc; 677 KitCgFuncSig sig; 678 KitCgDecl decl; 679 KitCgSym sym; 680 KitCgLocalAttrs attrs; 681 KitCgLocal param; 682 KitCgMemAccess mem; 683 uint32_t size; 684 685 memset(&opts, 0, sizeof opts); 686 opts.opt_level = 1; 687 ob = new_obj(c); 688 EXPECT(ob != NULL, "unary chain obj builder allocation failed"); 689 if (!ob) return 0; 690 cg = NULL; 691 (void)kit_cg_new(c, &cg); 692 if (cg) (void)kit_cg_begin(cg, ob, &opts); 693 EXPECT(cg != NULL, "unary chain cg allocation failed"); 694 if (!cg) { 695 kit_obj_builder_free(ob); 696 return 0; 697 } 698 699 memset(¶m_desc, 0, sizeof param_desc); 700 param_desc.type = i32_ty; 701 memset(&sig, 0, sizeof sig); 702 KitCgFuncResult sig_result; 703 memset(&sig_result, 0, sizeof sig_result); 704 sig_result.type = i32_ty; 705 sig.result = sig_result; 706 sig.params = ¶m_desc; 707 sig.nparams = 1; 708 sig.call_conv = KIT_CG_CC_TARGET_C; 709 710 memset(&decl, 0, sizeof decl); 711 decl.kind = KIT_CG_DECL_FUNC; 712 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 713 decl.display_name = decl.linkage_name; 714 decl.type = kit_cg_type_func(c, sig); 715 decl.sym.bind = KIT_SB_GLOBAL; 716 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 717 sym = kit_cg_decl(cg, decl); 718 EXPECT(sym != KIT_CG_SYM_NONE, "unary chain decl failed"); 719 720 kit_cg_func_begin(cg, sym); 721 memset(&attrs, 0, sizeof attrs); 722 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p")); 723 param = kit_cg_param(cg, 0, i32_ty, attrs); 724 EXPECT(param != KIT_CG_LOCAL_NONE, "unary chain param failed"); 725 memset(&mem, 0, sizeof mem); 726 mem.type = i32_ty; 727 mem.align = kit_cg_type_align(c, i32_ty); 728 kit_cg_push_local(cg, param); 729 kit_cg_load(cg, mem); 730 kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0); 731 kit_cg_int_unop(cg, KIT_CG_INT_BNOT, 0); 732 kit_cg_ret(cg); 733 kit_cg_func_end(cg); 734 735 finish_cg(cg, "unary chain"); 736 kit_cg_free(cg); 737 size = text_size(c, ob); 738 kit_obj_builder_free(ob); 739 return size; 740 } 741 742 static uint32_t cg_emit_local_shadow(KitCompiler* c, KitCgTypeId i32_ty, 743 const char* name) { 744 KitCodeOptions opts; 745 KitObjBuilder* ob; 746 KitCg* cg; 747 KitCgFuncSig sig; 748 KitCgDecl decl; 749 KitCgSym sym; 750 KitCgLocalAttrs attrs; 751 KitCgLocal local; 752 KitCgMemAccess mem; 753 uint32_t size; 754 755 memset(&opts, 0, sizeof opts); 756 opts.opt_level = 1; 757 ob = new_obj(c); 758 EXPECT(ob != NULL, "local shadow obj builder allocation failed"); 759 if (!ob) return 0; 760 cg = NULL; 761 (void)kit_cg_new(c, &cg); 762 if (cg) (void)kit_cg_begin(cg, ob, &opts); 763 EXPECT(cg != NULL, "local shadow cg allocation failed"); 764 if (!cg) { 765 kit_obj_builder_free(ob); 766 return 0; 767 } 768 769 memset(&sig, 0, sizeof sig); 770 KitCgFuncResult sig_result; 771 memset(&sig_result, 0, sizeof sig_result); 772 sig_result.type = i32_ty; 773 sig.result = sig_result; 774 sig.call_conv = KIT_CG_CC_TARGET_C; 775 776 memset(&decl, 0, sizeof decl); 777 decl.kind = KIT_CG_DECL_FUNC; 778 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 779 decl.display_name = decl.linkage_name; 780 decl.type = kit_cg_type_func(c, sig); 781 decl.sym.bind = KIT_SB_GLOBAL; 782 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 783 sym = kit_cg_decl(cg, decl); 784 EXPECT(sym != KIT_CG_SYM_NONE, "local shadow decl failed"); 785 786 kit_cg_func_begin(cg, sym); 787 memset(&attrs, 0, sizeof attrs); 788 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 789 local = kit_cg_local(cg, i32_ty, attrs); 790 EXPECT(local != KIT_CG_LOCAL_NONE, "local shadow local failed"); 791 memset(&mem, 0, sizeof mem); 792 mem.type = i32_ty; 793 mem.align = kit_cg_type_align(c, i32_ty); 794 kit_cg_push_local(cg, local); 795 kit_cg_push_int(cg, 40, i32_ty); 796 kit_cg_store(cg, mem); 797 kit_cg_push_local(cg, local); 798 kit_cg_load(cg, mem); 799 kit_cg_push_int(cg, 2, i32_ty); 800 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 801 kit_cg_ret(cg); 802 kit_cg_func_end(cg); 803 804 finish_cg(cg, "local shadow"); 805 kit_cg_free(cg); 806 size = text_size(c, ob); 807 kit_obj_builder_free(ob); 808 return size; 809 } 810 811 static uint32_t cg_emit_delayed_cmp(KitCompiler* c, KitCgTypeId i32_ty, 812 const char* name) { 813 KitCodeOptions opts; 814 KitObjBuilder* ob; 815 KitCg* cg; 816 KitCgFuncParam param_desc; 817 KitCgFuncSig sig; 818 KitCgDecl decl; 819 KitCgSym sym; 820 KitCgLocalAttrs attrs; 821 KitCgLocal param; 822 KitCgMemAccess mem; 823 uint32_t size; 824 825 memset(&opts, 0, sizeof opts); 826 opts.opt_level = 1; 827 ob = new_obj(c); 828 EXPECT(ob != NULL, "delayed cmp obj builder allocation failed"); 829 if (!ob) return 0; 830 cg = NULL; 831 (void)kit_cg_new(c, &cg); 832 if (cg) (void)kit_cg_begin(cg, ob, &opts); 833 EXPECT(cg != NULL, "delayed cmp cg allocation failed"); 834 if (!cg) { 835 kit_obj_builder_free(ob); 836 return 0; 837 } 838 839 memset(¶m_desc, 0, sizeof param_desc); 840 param_desc.type = i32_ty; 841 memset(&sig, 0, sizeof sig); 842 KitCgFuncResult sig_result; 843 memset(&sig_result, 0, sizeof sig_result); 844 sig_result.type = i32_ty; 845 sig.result = sig_result; 846 sig.params = ¶m_desc; 847 sig.nparams = 1; 848 sig.call_conv = KIT_CG_CC_TARGET_C; 849 850 memset(&decl, 0, sizeof decl); 851 decl.kind = KIT_CG_DECL_FUNC; 852 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 853 decl.display_name = decl.linkage_name; 854 decl.type = kit_cg_type_func(c, sig); 855 decl.sym.bind = KIT_SB_GLOBAL; 856 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 857 sym = kit_cg_decl(cg, decl); 858 EXPECT(sym != KIT_CG_SYM_NONE, "delayed cmp decl failed"); 859 860 kit_cg_func_begin(cg, sym); 861 memset(&attrs, 0, sizeof attrs); 862 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p")); 863 param = kit_cg_param(cg, 0, i32_ty, attrs); 864 EXPECT(param != KIT_CG_LOCAL_NONE, "delayed cmp param failed"); 865 memset(&mem, 0, sizeof mem); 866 mem.type = i32_ty; 867 mem.align = kit_cg_type_align(c, i32_ty); 868 kit_cg_push_local(cg, param); 869 kit_cg_load(cg, mem); 870 kit_cg_push_int(cg, 40, i32_ty); 871 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 872 kit_cg_push_int(cg, 2, i32_ty); 873 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 874 kit_cg_push_int(cg, 42, i32_ty); 875 kit_cg_int_cmp(cg, KIT_CG_INT_EQ); 876 kit_cg_ret(cg); 877 kit_cg_func_end(cg); 878 879 finish_cg(cg, "delayed cmp"); 880 kit_cg_free(cg); 881 size = text_size(c, ob); 882 kit_obj_builder_free(ob); 883 return size; 884 } 885 886 static uint32_t cg_emit_delayed_store(KitCompiler* c, KitCgTypeId i32_ty, 887 const char* name) { 888 KitCodeOptions opts; 889 KitObjBuilder* ob; 890 KitCg* cg; 891 KitCgFuncParam param_desc; 892 KitCgFuncSig sig; 893 KitCgDecl decl; 894 KitCgSym sym; 895 KitCgLocalAttrs attrs; 896 KitCgLocal param; 897 KitCgLocal local; 898 KitCgMemAccess mem; 899 uint32_t size; 900 901 memset(&opts, 0, sizeof opts); 902 opts.opt_level = 1; 903 ob = new_obj(c); 904 EXPECT(ob != NULL, "delayed store obj builder allocation failed"); 905 if (!ob) return 0; 906 cg = NULL; 907 (void)kit_cg_new(c, &cg); 908 if (cg) (void)kit_cg_begin(cg, ob, &opts); 909 EXPECT(cg != NULL, "delayed store cg allocation failed"); 910 if (!cg) { 911 kit_obj_builder_free(ob); 912 return 0; 913 } 914 915 memset(¶m_desc, 0, sizeof param_desc); 916 param_desc.type = i32_ty; 917 memset(&sig, 0, sizeof sig); 918 KitCgFuncResult sig_result; 919 memset(&sig_result, 0, sizeof sig_result); 920 sig_result.type = i32_ty; 921 sig.result = sig_result; 922 sig.params = ¶m_desc; 923 sig.nparams = 1; 924 sig.call_conv = KIT_CG_CC_TARGET_C; 925 926 memset(&decl, 0, sizeof decl); 927 decl.kind = KIT_CG_DECL_FUNC; 928 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 929 decl.display_name = decl.linkage_name; 930 decl.type = kit_cg_type_func(c, sig); 931 decl.sym.bind = KIT_SB_GLOBAL; 932 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 933 sym = kit_cg_decl(cg, decl); 934 EXPECT(sym != KIT_CG_SYM_NONE, "delayed store decl failed"); 935 936 kit_cg_func_begin(cg, sym); 937 memset(&attrs, 0, sizeof attrs); 938 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("p")); 939 param = kit_cg_param(cg, 0, i32_ty, attrs); 940 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 941 local = kit_cg_local(cg, i32_ty, attrs); 942 EXPECT(param != KIT_CG_LOCAL_NONE, "delayed store param failed"); 943 EXPECT(local != KIT_CG_LOCAL_NONE, "delayed store local failed"); 944 memset(&mem, 0, sizeof mem); 945 mem.type = i32_ty; 946 mem.align = kit_cg_type_align(c, i32_ty); 947 kit_cg_push_local(cg, local); 948 kit_cg_push_local(cg, param); 949 kit_cg_load(cg, mem); 950 kit_cg_push_int(cg, 40, i32_ty); 951 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 952 kit_cg_push_int(cg, 2, i32_ty); 953 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 954 kit_cg_store(cg, mem); 955 kit_cg_push_local(cg, local); 956 kit_cg_load(cg, mem); 957 kit_cg_ret(cg); 958 kit_cg_func_end(cg); 959 960 finish_cg(cg, "delayed store"); 961 kit_cg_free(cg); 962 size = text_size(c, ob); 963 kit_obj_builder_free(ob); 964 return size; 965 } 966 967 static uint32_t cg_emit_delayed_pressure(KitCompiler* c, KitCgTypeId i32_ty, 968 const char* name) { 969 enum { NPARAMS = 13 }; 970 KitCodeOptions opts; 971 KitObjBuilder* ob; 972 KitCg* cg; 973 KitCgFuncParam param_desc[NPARAMS]; 974 KitCgFuncSig sig; 975 KitCgDecl decl; 976 KitCgSym sym; 977 KitCgLocalAttrs attrs; 978 KitCgLocal params[NPARAMS]; 979 KitCgMemAccess mem; 980 uint32_t size; 981 982 memset(&opts, 0, sizeof opts); 983 opts.opt_level = 1; 984 ob = new_obj(c); 985 EXPECT(ob != NULL, "delayed pressure obj builder allocation failed"); 986 if (!ob) return 0; 987 cg = NULL; 988 (void)kit_cg_new(c, &cg); 989 if (cg) (void)kit_cg_begin(cg, ob, &opts); 990 EXPECT(cg != NULL, "delayed pressure cg allocation failed"); 991 if (!cg) { 992 kit_obj_builder_free(ob); 993 return 0; 994 } 995 996 memset(param_desc, 0, sizeof param_desc); 997 for (uint32_t i = 0; i < NPARAMS; ++i) param_desc[i].type = i32_ty; 998 memset(&sig, 0, sizeof sig); 999 KitCgFuncResult sig_result; 1000 memset(&sig_result, 0, sizeof sig_result); 1001 sig_result.type = i32_ty; 1002 sig.result = sig_result; 1003 sig.params = param_desc; 1004 sig.nparams = NPARAMS; 1005 sig.call_conv = KIT_CG_CC_TARGET_C; 1006 1007 memset(&decl, 0, sizeof decl); 1008 decl.kind = KIT_CG_DECL_FUNC; 1009 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 1010 decl.display_name = decl.linkage_name; 1011 decl.type = kit_cg_type_func(c, sig); 1012 decl.sym.bind = KIT_SB_GLOBAL; 1013 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1014 sym = kit_cg_decl(cg, decl); 1015 EXPECT(sym != KIT_CG_SYM_NONE, "delayed pressure decl failed"); 1016 1017 kit_cg_func_begin(cg, sym); 1018 memset(&attrs, 0, sizeof attrs); 1019 memset(&mem, 0, sizeof mem); 1020 mem.type = i32_ty; 1021 mem.align = kit_cg_type_align(c, i32_ty); 1022 for (uint32_t i = 0; i < NPARAMS; ++i) { 1023 char pname[8]; 1024 snprintf(pname, sizeof pname, "p%u", (unsigned)i); 1025 attrs.name = kit_sym_intern(c, kit_slice_cstr(pname)); 1026 params[i] = kit_cg_param(cg, i, i32_ty, attrs); 1027 EXPECT(params[i] != KIT_CG_LOCAL_NONE, "delayed pressure param failed"); 1028 } 1029 1030 for (uint32_t i = 0; i + 1 < NPARAMS; ++i) { 1031 kit_cg_push_local(cg, params[i]); 1032 kit_cg_load(cg, mem); 1033 kit_cg_push_int(cg, 1, i32_ty); 1034 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 1035 } 1036 kit_cg_push_local(cg, params[NPARAMS - 1]); 1037 kit_cg_load(cg, mem); 1038 kit_cg_drop(cg); 1039 for (uint32_t i = 0; i + 1 < NPARAMS; ++i) kit_cg_drop(cg); 1040 kit_cg_push_int(cg, 0, i32_ty); 1041 kit_cg_ret(cg); 1042 kit_cg_func_end(cg); 1043 1044 finish_cg(cg, "delayed pressure"); 1045 kit_cg_free(cg); 1046 size = text_size(c, ob); 1047 kit_obj_builder_free(ob); 1048 return size; 1049 } 1050 1051 typedef enum CgShadowBoundary { 1052 CG_SHADOW_LABEL, 1053 CG_SHADOW_BRANCH, 1054 CG_SHADOW_ADDR, 1055 CG_SHADOW_VOLATILE, 1056 CG_SHADOW_INDIRECT_STORE, 1057 } CgShadowBoundary; 1058 1059 static uint32_t cg_emit_local_shadow_boundary(KitCompiler* c, 1060 KitCgTypeId i32_ty, 1061 const char* name, 1062 CgShadowBoundary boundary) { 1063 KitCodeOptions opts; 1064 KitObjBuilder* ob; 1065 KitCg* cg; 1066 KitCgFuncSig sig; 1067 KitCgDecl decl; 1068 KitCgSym sym; 1069 KitCgLocalAttrs attrs; 1070 KitCgLocal local; 1071 KitCgMemAccess mem; 1072 uint32_t size; 1073 1074 memset(&opts, 0, sizeof opts); 1075 opts.opt_level = 1; 1076 ob = new_obj(c); 1077 EXPECT(ob != NULL, "local shadow boundary obj builder allocation failed"); 1078 if (!ob) return 0; 1079 cg = NULL; 1080 (void)kit_cg_new(c, &cg); 1081 if (cg) (void)kit_cg_begin(cg, ob, &opts); 1082 EXPECT(cg != NULL, "local shadow boundary cg allocation failed"); 1083 if (!cg) { 1084 kit_obj_builder_free(ob); 1085 return 0; 1086 } 1087 1088 memset(&sig, 0, sizeof sig); 1089 KitCgFuncResult sig_result; 1090 memset(&sig_result, 0, sizeof sig_result); 1091 sig_result.type = i32_ty; 1092 sig.result = sig_result; 1093 sig.call_conv = KIT_CG_CC_TARGET_C; 1094 1095 memset(&decl, 0, sizeof decl); 1096 decl.kind = KIT_CG_DECL_FUNC; 1097 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 1098 decl.display_name = decl.linkage_name; 1099 decl.type = kit_cg_type_func(c, sig); 1100 decl.sym.bind = KIT_SB_GLOBAL; 1101 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1102 sym = kit_cg_decl(cg, decl); 1103 EXPECT(sym != KIT_CG_SYM_NONE, "local shadow boundary decl failed"); 1104 1105 kit_cg_func_begin(cg, sym); 1106 memset(&attrs, 0, sizeof attrs); 1107 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 1108 local = kit_cg_local(cg, i32_ty, attrs); 1109 EXPECT(local != KIT_CG_LOCAL_NONE, "local shadow boundary local failed"); 1110 memset(&mem, 0, sizeof mem); 1111 mem.type = i32_ty; 1112 mem.align = kit_cg_type_align(c, i32_ty); 1113 1114 kit_cg_push_local(cg, local); 1115 kit_cg_push_int(cg, 40, i32_ty); 1116 kit_cg_store(cg, mem); 1117 1118 switch (boundary) { 1119 case CG_SHADOW_LABEL: { 1120 KitCgLabel label = kit_cg_label_new(cg); 1121 kit_cg_label_place(cg, label); 1122 break; 1123 } 1124 case CG_SHADOW_BRANCH: { 1125 KitCgLabel label = kit_cg_label_new(cg); 1126 kit_cg_push_int(cg, 0, i32_ty); 1127 kit_cg_branch_true(cg, label); 1128 kit_cg_label_place(cg, label); 1129 break; 1130 } 1131 case CG_SHADOW_ADDR: 1132 kit_cg_push_local_addr(cg, local); 1133 kit_cg_drop(cg); 1134 break; 1135 case CG_SHADOW_VOLATILE: 1136 mem.flags = KIT_CG_MEM_VOLATILE; 1137 kit_cg_push_local(cg, local); 1138 kit_cg_load(cg, mem); 1139 kit_cg_drop(cg); 1140 mem.flags = 0; 1141 break; 1142 case CG_SHADOW_INDIRECT_STORE: 1143 kit_cg_push_local_addr(cg, local); 1144 kit_cg_deref(cg, 0); /* pointer VALUE -> PLACE for the store */ 1145 kit_cg_push_int(cg, 41, i32_ty); 1146 kit_cg_store(cg, mem); 1147 break; 1148 } 1149 1150 kit_cg_push_local(cg, local); 1151 kit_cg_load(cg, mem); 1152 kit_cg_push_int(cg, 2, i32_ty); 1153 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 1154 kit_cg_ret(cg); 1155 kit_cg_func_end(cg); 1156 1157 finish_cg(cg, "local shadow boundary"); 1158 kit_cg_free(cg); 1159 size = text_size(c, ob); 1160 kit_obj_builder_free(ob); 1161 return size; 1162 } 1163 1164 static uint32_t cg_emit_local_shadow_partial_store(KitCompiler* c, 1165 KitCgTypeId i32_ty, 1166 KitCgTypeId i8_ty, 1167 const char* name) { 1168 KitCodeOptions opts; 1169 KitObjBuilder* ob; 1170 KitCg* cg; 1171 KitCgFuncSig sig; 1172 KitCgDecl decl; 1173 KitCgSym sym; 1174 KitCgLocalAttrs attrs; 1175 KitCgLocal local; 1176 KitCgMemAccess mem_i32; 1177 KitCgMemAccess mem_i8; 1178 uint32_t size; 1179 1180 memset(&opts, 0, sizeof opts); 1181 opts.opt_level = 1; 1182 ob = new_obj(c); 1183 EXPECT(ob != NULL, "partial shadow obj builder allocation failed"); 1184 if (!ob) return 0; 1185 cg = NULL; 1186 (void)kit_cg_new(c, &cg); 1187 if (cg) (void)kit_cg_begin(cg, ob, &opts); 1188 EXPECT(cg != NULL, "partial shadow cg allocation failed"); 1189 if (!cg) { 1190 kit_obj_builder_free(ob); 1191 return 0; 1192 } 1193 1194 memset(&sig, 0, sizeof sig); 1195 KitCgFuncResult sig_result; 1196 memset(&sig_result, 0, sizeof sig_result); 1197 sig_result.type = i32_ty; 1198 sig.result = sig_result; 1199 sig.call_conv = KIT_CG_CC_TARGET_C; 1200 1201 memset(&decl, 0, sizeof decl); 1202 decl.kind = KIT_CG_DECL_FUNC; 1203 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 1204 decl.display_name = decl.linkage_name; 1205 decl.type = kit_cg_type_func(c, sig); 1206 decl.sym.bind = KIT_SB_GLOBAL; 1207 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1208 sym = kit_cg_decl(cg, decl); 1209 EXPECT(sym != KIT_CG_SYM_NONE, "partial shadow decl failed"); 1210 1211 kit_cg_func_begin(cg, sym); 1212 memset(&attrs, 0, sizeof attrs); 1213 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("x")); 1214 local = kit_cg_local(cg, i32_ty, attrs); 1215 EXPECT(local != KIT_CG_LOCAL_NONE, "partial shadow local failed"); 1216 memset(&mem_i32, 0, sizeof mem_i32); 1217 mem_i32.type = i32_ty; 1218 mem_i32.align = kit_cg_type_align(c, i32_ty); 1219 memset(&mem_i8, 0, sizeof mem_i8); 1220 mem_i8.type = i8_ty; 1221 mem_i8.align = kit_cg_type_align(c, i8_ty); 1222 1223 kit_cg_push_local(cg, local); 1224 kit_cg_push_int(cg, 40, i32_ty); 1225 kit_cg_store(cg, mem_i32); 1226 kit_cg_push_local(cg, local); 1227 kit_cg_push_int(cg, 7, i8_ty); 1228 kit_cg_store(cg, mem_i8); 1229 kit_cg_push_local(cg, local); 1230 kit_cg_load(cg, mem_i32); 1231 kit_cg_push_int(cg, 2, i32_ty); 1232 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 1233 kit_cg_ret(cg); 1234 kit_cg_func_end(cg); 1235 1236 finish_cg(cg, "partial shadow"); 1237 kit_cg_free(cg); 1238 size = text_size(c, ob); 1239 kit_obj_builder_free(ob); 1240 return size; 1241 } 1242 1243 static void exercise_cg_constfold_phases(KitCompiler* c, KitCgTypeId i32_ty, 1244 KitCgTypeId i8_ty) { 1245 uint32_t delayed_size = 1246 cg_emit_delayed_chain(c, i32_ty, "cg_delayed_chain_o1"); 1247 uint32_t unary_size = cg_emit_unary_chain(c, i32_ty, "cg_unary_chain_o1"); 1248 uint32_t local_size = cg_emit_local_shadow(c, i32_ty, "cg_local_shadow_o1"); 1249 uint32_t delayed_cmp_size = 1250 cg_emit_delayed_cmp(c, i32_ty, "cg_delayed_cmp_o1"); 1251 uint32_t delayed_store_size = 1252 cg_emit_delayed_store(c, i32_ty, "cg_delayed_store_o1"); 1253 uint32_t pressure_size = 1254 cg_emit_delayed_pressure(c, i32_ty, "cg_delayed_pressure_o1"); 1255 uint32_t label_size = cg_emit_local_shadow_boundary( 1256 c, i32_ty, "cg_shadow_label_o1", CG_SHADOW_LABEL); 1257 uint32_t branch_size = cg_emit_local_shadow_boundary( 1258 c, i32_ty, "cg_shadow_branch_o1", CG_SHADOW_BRANCH); 1259 uint32_t addr_size = cg_emit_local_shadow_boundary( 1260 c, i32_ty, "cg_shadow_addr_o1", CG_SHADOW_ADDR); 1261 uint32_t volatile_size = cg_emit_local_shadow_boundary( 1262 c, i32_ty, "cg_shadow_volatile_o1", CG_SHADOW_VOLATILE); 1263 uint32_t indirect_size = cg_emit_local_shadow_boundary( 1264 c, i32_ty, "cg_shadow_indirect_o1", CG_SHADOW_INDIRECT_STORE); 1265 uint32_t partial_size = cg_emit_local_shadow_partial_store( 1266 c, i32_ty, i8_ty, "cg_shadow_partial_o1"); 1267 1268 EXPECT(delayed_size <= 56, 1269 "delayed arithmetic chain should materialize as one add, text " 1270 "size=%u", 1271 delayed_size); 1272 EXPECT(unary_size <= 48, 1273 "delayed unary chain should collapse before return, text size=%u", 1274 unary_size); 1275 EXPECT(local_size <= 32, 1276 "local constant shadow should fold x=40; return x+2, text size=%u", 1277 local_size); 1278 EXPECT(delayed_cmp_size <= 64, 1279 "delayed arithmetic consumed by compare should stay compact, text " 1280 "size=%u", 1281 delayed_cmp_size); 1282 EXPECT(delayed_store_size <= 64, 1283 "delayed arithmetic forced by store should stay compact, text size=%u", 1284 delayed_store_size); 1285 EXPECT(pressure_size > 0, 1286 "delayed arithmetic pressure materialization should emit code"); 1287 EXPECT(label_size > local_size, 1288 "label should clear local shadow, label=%u folded=%u", label_size, 1289 local_size); 1290 EXPECT(branch_size > local_size, 1291 "branch should clear local shadow, branch=%u folded=%u", branch_size, 1292 local_size); 1293 EXPECT(addr_size > local_size, 1294 "address-taking should clear local shadow, addr=%u folded=%u", 1295 addr_size, local_size); 1296 EXPECT(volatile_size > local_size, 1297 "volatile access should clear local shadow, volatile=%u folded=%u", 1298 volatile_size, local_size); 1299 EXPECT(indirect_size > local_size, 1300 "indirect store should clear local shadow, indirect=%u folded=%u", 1301 indirect_size, local_size); 1302 EXPECT(partial_size > local_size, 1303 "partial-width store should clear local shadow, partial=%u folded=%u", 1304 partial_size, local_size); 1305 } 1306 1307 static void exercise_cg_memop_constfold_shape(KitCompiler* c, 1308 KitCgTypeId i32_ty, 1309 KitCgTypeId i64_ty, 1310 KitCgTypeId ptr_i32) { 1311 KitCodeOptions opts; 1312 KitObjBuilder* ob; 1313 KitWriter* dump = NULL; 1314 KitCg* cg; 1315 KitCgFuncParam params[2]; 1316 KitCgFuncSig sig; 1317 KitCgDecl decl; 1318 KitCgSym fn_sym; 1319 KitCgSym data_sym; 1320 KitCgLocalAttrs attrs; 1321 KitCgLocal base_param; 1322 KitCgLocal idx_param; 1323 KitCgMemAccess mem_i32; 1324 KitCgMemAccess mem_i64; 1325 KitCgMemAccess mem_ptr; 1326 const uint8_t data[64] = {0}; 1327 const uint8_t* bytes; 1328 size_t len = 0; 1329 char text[8192]; 1330 size_t copy_len; 1331 1332 memset(&opts, 0, sizeof opts); 1333 opts.opt_level = 1; 1334 opts.emit_ir = true; 1335 EXPECT(kit_writer_mem(&g_u.heap, &dump) == KIT_OK && dump != NULL, 1336 "memop fold dump writer allocation failed"); 1337 if (!dump) return; 1338 opts.ir_dump_writer = dump; 1339 1340 ob = new_obj(c); 1341 EXPECT(ob != NULL, "memop fold obj builder allocation failed"); 1342 if (!ob) { 1343 kit_writer_close(dump); 1344 return; 1345 } 1346 cg = NULL; 1347 (void)kit_cg_new(c, &cg); 1348 if (cg) (void)kit_cg_begin(cg, ob, &opts); 1349 EXPECT(cg != NULL, "memop fold cg allocation failed"); 1350 if (!cg) { 1351 kit_obj_builder_free(ob); 1352 kit_writer_close(dump); 1353 return; 1354 } 1355 1356 data_sym = kit_cg_const_data(cg, data, sizeof data, 4, i32_ty); 1357 EXPECT(data_sym != KIT_CG_SYM_NONE, "memop fold const data failed"); 1358 1359 memset(params, 0, sizeof params); 1360 params[0].type = ptr_i32; 1361 params[1].type = i64_ty; 1362 memset(&sig, 0, sizeof sig); 1363 KitCgFuncResult sig_result; 1364 memset(&sig_result, 0, sizeof sig_result); 1365 sig_result.type = i32_ty; 1366 sig.result = sig_result; 1367 sig.params = params; 1368 sig.nparams = 2; 1369 sig.call_conv = KIT_CG_CC_TARGET_C; 1370 1371 memset(&decl, 0, sizeof decl); 1372 decl.kind = KIT_CG_DECL_FUNC; 1373 decl.linkage_name = 1374 kit_sym_intern(c, KIT_SLICE_LIT("cg_memop_constfold_shape")); 1375 decl.display_name = decl.linkage_name; 1376 decl.type = kit_cg_type_func(c, sig); 1377 decl.sym.bind = KIT_SB_GLOBAL; 1378 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1379 fn_sym = kit_cg_decl(cg, decl); 1380 EXPECT(fn_sym != KIT_CG_SYM_NONE, "memop fold function decl failed"); 1381 1382 memset(&mem_i32, 0, sizeof mem_i32); 1383 mem_i32.type = i32_ty; 1384 mem_i32.align = kit_cg_type_align(c, i32_ty); 1385 memset(&mem_i64, 0, sizeof mem_i64); 1386 mem_i64.type = i64_ty; 1387 mem_i64.align = kit_cg_type_align(c, i64_ty); 1388 memset(&mem_ptr, 0, sizeof mem_ptr); 1389 mem_ptr.type = ptr_i32; 1390 mem_ptr.align = kit_cg_type_align(c, ptr_i32); 1391 1392 kit_cg_func_begin(cg, fn_sym); 1393 memset(&attrs, 0, sizeof attrs); 1394 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("base")); 1395 base_param = kit_cg_param(cg, 0, ptr_i32, attrs); 1396 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("idx")); 1397 idx_param = kit_cg_param(cg, 1, i64_ty, attrs); 1398 EXPECT(base_param != KIT_CG_LOCAL_NONE && idx_param != KIT_CG_LOCAL_NONE, 1399 "memop fold params failed"); 1400 1401 /* Constant base addend + constant index*scale + offset: 11 + 3*8 + 5. */ 1402 kit_cg_push_symbol_addr(cg, data_sym, 11); 1403 kit_cg_push_int(cg, 3, i64_ty); 1404 kit_cg_elem_scaled(cg, 8, 5); 1405 kit_cg_load(cg, mem_i32); 1406 kit_cg_drop(cg); 1407 1408 /* Non-global offsets wider than the memop displacement are materialized into 1409 * the base instead of truncated to i32. */ 1410 kit_cg_push_local(cg, base_param); 1411 kit_cg_load(cg, mem_ptr); 1412 kit_cg_push_local(cg, idx_param); 1413 kit_cg_load(cg, mem_i64); 1414 kit_cg_elem_scaled(cg, 8, 2147483656LL); 1415 kit_cg_load(cg, mem_i32); 1416 kit_cg_drop(cg); 1417 1418 /* Dynamic base and index keep the scale and offset on the memory operand. */ 1419 kit_cg_push_local(cg, base_param); 1420 kit_cg_load(cg, mem_ptr); 1421 kit_cg_push_local(cg, idx_param); 1422 kit_cg_load(cg, mem_i64); 1423 kit_cg_elem_scaled(cg, 8, 5); 1424 kit_cg_load(cg, mem_i32); 1425 kit_cg_ret(cg); 1426 kit_cg_func_end(cg); 1427 1428 EXPECT(kit_cg_finish(cg, NULL) == KIT_OK, "memop fold cg finish failed"); 1429 bytes = kit_writer_mem_bytes(dump, &len); 1430 copy_len = len < sizeof text - 1u ? len : sizeof text - 1u; 1431 if (bytes && copy_len) memcpy(text, bytes, copy_len); 1432 text[copy_len] = '\0'; 1433 EXPECT(bytes != NULL && len > 0 && len < sizeof text, 1434 "memop fold IR dump missing or too large"); 1435 EXPECT(strstr(text, "addr_of") == NULL, 1436 "memop fold should not materialize folded addresses:\n%s", text); 1437 EXPECT(strstr(text, "sym#") != NULL && strstr(text, "+40") != NULL, 1438 "memop fold should fold symbol base/addend/index/offset:\n%s", text); 1439 EXPECT(strstr(text, "*8+5") != NULL, 1440 "memop fold should preserve dynamic index scale/offset:\n%s", text); 1441 EXPECT(strstr(text, "imm:2147483656") != NULL, 1442 "memop fold should materialize offsets wider than i32:\n%s", text); 1443 1444 kit_cg_free(cg); 1445 kit_obj_builder_free(ob); 1446 kit_writer_close(dump); 1447 } 1448 1449 static KitCg* begin_void_cg_func(KitCompiler* c, const char* name, 1450 KitObjBuilder** ob_out) { 1451 KitCodeOptions opts; 1452 KitObjBuilder* ob; 1453 KitCg* cg; 1454 KitCgFuncSig sig; 1455 KitCgFuncResult result; 1456 KitCgDecl decl; 1457 KitCgSym sym; 1458 1459 if (ob_out) *ob_out = NULL; 1460 memset(&opts, 0, sizeof opts); 1461 ob = new_obj(c); 1462 EXPECT(ob != NULL, "%s obj builder allocation failed", name); 1463 if (!ob) return NULL; 1464 cg = NULL; 1465 EXPECT(kit_cg_new(c, &cg) == KIT_OK && cg != NULL, "%s cg allocation failed", 1466 name); 1467 if (!cg) { 1468 kit_obj_builder_free(ob); 1469 return NULL; 1470 } 1471 EXPECT(kit_cg_begin(cg, ob, &opts) == KIT_OK, "%s cg begin failed", name); 1472 1473 memset(&sig, 0, sizeof sig); 1474 memset(&result, 0, sizeof result); 1475 result.type = kit_cg_type_builtin(c, KIT_CG_BUILTIN_VOID); 1476 sig.result = result; 1477 sig.call_conv = KIT_CG_CC_TARGET_C; 1478 memset(&decl, 0, sizeof decl); 1479 decl.kind = KIT_CG_DECL_FUNC; 1480 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 1481 decl.display_name = decl.linkage_name; 1482 decl.type = kit_cg_type_func(c, sig); 1483 decl.sym.bind = KIT_SB_LOCAL; 1484 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1485 sym = kit_cg_decl(cg, decl); 1486 EXPECT(sym != KIT_CG_SYM_NONE, "%s decl failed", name); 1487 if (sym == KIT_CG_SYM_NONE) { 1488 kit_cg_free(cg); 1489 kit_obj_builder_free(ob); 1490 return NULL; 1491 } 1492 kit_cg_func_begin(cg, sym); 1493 if (ob_out) *ob_out = ob; 1494 return cg; 1495 } 1496 1497 static void exercise_cg_slot_lang_facts(KitCompiler* c, KitCgTypeId i32_ty) { 1498 static const char tag_a[] = "slot-a"; 1499 static const char tag_b[] = "slot-b"; 1500 KitObjBuilder* ob; 1501 KitCg* cg = begin_void_cg_func(c, "cg_slot_lang_facts", &ob); 1502 KitCgSlotInfo info; 1503 KitCgScope scope; 1504 if (!cg) return; 1505 1506 kit_cg_push_int(cg, 1, i32_ty); 1507 kit_cg_retag_top(cg, tag_a, 0x0003u); 1508 kit_cg_dup(cg); 1509 info = kit_cg_slot_info(cg, 0); 1510 EXPECT(info.cg_type == i32_ty && info.lang_type == tag_a && 1511 info.lang_flags == 0x0003u, 1512 "dup should copy top slot facts"); 1513 info = kit_cg_slot_info(cg, 1); 1514 EXPECT(info.lang_type == tag_a && info.lang_flags == 0x0003u, 1515 "dup should preserve original slot facts"); 1516 kit_cg_retag_at(cg, 1, tag_b, 0x0010u); 1517 kit_cg_set_top_flags(cg, 0x0004u, 0x0001u); 1518 info = kit_cg_slot_info(cg, 0); 1519 EXPECT(info.lang_type == tag_a && info.lang_flags == 0x0006u, 1520 "set_top_flags should update only top flags"); 1521 info = kit_cg_slot_info(cg, 1); 1522 EXPECT(info.lang_type == tag_b && info.lang_flags == 0x0010u, 1523 "retag_at should update depth-selected slot"); 1524 kit_cg_drop(cg); 1525 kit_cg_drop(cg); 1526 1527 kit_cg_push_int(cg, 2, i32_ty); 1528 kit_cg_retag_top(cg, tag_a, 0x00ffu); 1529 kit_cg_push_int(cg, 3, i32_ty); 1530 kit_cg_retag_top(cg, tag_b, 0x00eeu); 1531 kit_cg_int_binop(cg, KIT_CG_INT_ADD, 0); 1532 info = kit_cg_slot_info(cg, 0); 1533 EXPECT( 1534 info.cg_type == i32_ty && info.lang_type == NULL && info.lang_flags == 0, 1535 "fresh binop producer should clear slot facts"); 1536 kit_cg_drop(cg); 1537 1538 scope = kit_cg_block_begin_value(cg, i32_ty); 1539 kit_cg_push_int(cg, 4, i32_ty); 1540 kit_cg_retag_top(cg, tag_b, 0x0033u); 1541 kit_cg_scope_end(cg, scope); 1542 info = kit_cg_slot_info(cg, 0); 1543 EXPECT(info.cg_type == i32_ty && info.lang_type == tag_b && 1544 info.lang_flags == 0x0033u, 1545 "scope result mover should preserve slot facts"); 1546 kit_cg_drop(cg); 1547 1548 kit_cg_ret(cg); 1549 kit_cg_func_end(cg); 1550 kit_cg_free(cg); 1551 kit_obj_builder_free(ob); 1552 } 1553 1554 static void exercise_cg_field_at_store_keep(KitCompiler* c, KitCgTypeId i32_ty, 1555 KitCgTypeId rec_ty) { 1556 static const char value_tag[] = "assigned-value"; 1557 KitObjBuilder* ob; 1558 KitCg* cg = begin_void_cg_func(c, "cg_field_at_store_keep", &ob); 1559 KitCgLocalAttrs attrs; 1560 KitCgLocal local; 1561 KitCgMemAccess mem; 1562 KitCgSlotInfo info; 1563 if (!cg) return; 1564 1565 memset(&attrs, 0, sizeof attrs); 1566 attrs.name = kit_sym_intern(c, KIT_SLICE_LIT("r")); 1567 local = kit_cg_local(cg, rec_ty, attrs); 1568 EXPECT(local != KIT_CG_LOCAL_NONE, "field_at local allocation failed"); 1569 1570 memset(&mem, 0, sizeof mem); 1571 mem.type = i32_ty; 1572 mem.align = kit_cg_type_align(c, i32_ty); 1573 1574 kit_cg_push_local(cg, local); 1575 kit_cg_field_at(cg, 4, i32_ty); 1576 kit_cg_push_int(cg, 42, i32_ty); 1577 kit_cg_retag_top(cg, value_tag, 0x0042u); 1578 kit_cg_store_keep(cg, mem); 1579 EXPECT(kit_cg_stack_depth(cg) == 1u, "store_keep should leave one value"); 1580 info = kit_cg_slot_info(cg, 0); 1581 EXPECT(info.cg_type == i32_ty && info.lang_type == value_tag && 1582 info.lang_flags == 0x0042u, 1583 "store_keep should preserve assigned value slot facts"); 1584 kit_cg_drop(cg); 1585 1586 kit_cg_push_local(cg, local); 1587 kit_cg_field_at(cg, 4, i32_ty); 1588 kit_cg_load(cg, mem); 1589 info = kit_cg_slot_info(cg, 0); 1590 EXPECT( 1591 info.cg_type == i32_ty && info.lang_type == NULL && info.lang_flags == 0, 1592 "load through field_at should produce a freshly untagged value"); 1593 kit_cg_drop(cg); 1594 1595 kit_cg_ret(cg); 1596 kit_cg_func_end(cg); 1597 kit_cg_free(cg); 1598 kit_obj_builder_free(ob); 1599 } 1600 1601 typedef struct BadStoreCtx { 1602 KitCompiler* c; 1603 KitCgTypeId i32_ty; 1604 KitCgTypeId i64_ty; 1605 KitCgTypeId rec_ty; 1606 } BadStoreCtx; 1607 1608 static KitCg* cg_begin_bad_store_func(KitCompiler* c, const char* name) { 1609 KitCodeOptions opts; 1610 KitObjBuilder* ob; 1611 KitCg* cg; 1612 KitCgFuncSig sig; 1613 KitCgFuncResult result; 1614 KitCgDecl decl; 1615 KitCgSym sym; 1616 1617 memset(&opts, 0, sizeof opts); 1618 ob = new_obj(c); 1619 EXPECT(ob != NULL, "bad-store obj builder allocation failed"); 1620 if (!ob) return NULL; 1621 cg = NULL; 1622 (void)kit_cg_new(c, &cg); 1623 if (cg) (void)kit_cg_begin(cg, ob, &opts); 1624 EXPECT(cg != NULL, "bad-store cg allocation failed"); 1625 if (!cg) { 1626 kit_obj_builder_free(ob); 1627 return NULL; 1628 } 1629 1630 memset(&sig, 0, sizeof sig); 1631 memset(&result, 0, sizeof result); 1632 result.type = kit_cg_type_builtin(c, KIT_CG_BUILTIN_VOID); 1633 sig.result = result; 1634 sig.call_conv = KIT_CG_CC_TARGET_C; 1635 memset(&decl, 0, sizeof decl); 1636 decl.kind = KIT_CG_DECL_FUNC; 1637 decl.linkage_name = kit_sym_intern(c, kit_slice_cstr(name)); 1638 decl.display_name = decl.linkage_name; 1639 decl.type = kit_cg_type_func(c, sig); 1640 decl.sym.bind = KIT_SB_LOCAL; 1641 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1642 sym = kit_cg_decl(cg, decl); 1643 EXPECT(sym != KIT_CG_SYM_NONE, "bad-store function decl failed"); 1644 if (sym == KIT_CG_SYM_NONE) { 1645 kit_cg_free(cg); 1646 kit_obj_builder_free(ob); 1647 return NULL; 1648 } 1649 kit_cg_func_begin(cg, sym); 1650 return cg; 1651 } 1652 1653 static void run_bad_scalar_access_to_aggregate(void* arg) { 1654 BadStoreCtx* ctx = (BadStoreCtx*)arg; 1655 KitCgLocal local; 1656 KitCgLocalAttrs attrs; 1657 KitCgMemAccess mem; 1658 KitCg* cg = 1659 cg_begin_bad_store_func(ctx->c, "cg_bad_scalar_access_to_aggregate"); 1660 if (!cg) return; 1661 1662 memset(&attrs, 0, sizeof attrs); 1663 local = kit_cg_local(cg, ctx->rec_ty, attrs); 1664 memset(&mem, 0, sizeof mem); 1665 mem.type = ctx->i32_ty; 1666 mem.align = kit_cg_type_align(ctx->c, ctx->i32_ty); 1667 kit_cg_push_local(cg, local); 1668 kit_cg_push_int(cg, 42, ctx->i32_ty); 1669 kit_cg_store(cg, mem); 1670 } 1671 1672 static void run_bad_store_value_size(void* arg) { 1673 BadStoreCtx* ctx = (BadStoreCtx*)arg; 1674 KitCgLocal local; 1675 KitCgLocalAttrs attrs; 1676 KitCgMemAccess mem; 1677 KitCg* cg = cg_begin_bad_store_func(ctx->c, "cg_bad_store_value_size"); 1678 if (!cg) return; 1679 1680 memset(&attrs, 0, sizeof attrs); 1681 local = kit_cg_local(cg, ctx->i64_ty, attrs); 1682 memset(&mem, 0, sizeof mem); 1683 mem.type = ctx->i64_ty; 1684 mem.align = kit_cg_type_align(ctx->c, ctx->i64_ty); 1685 kit_cg_push_local(cg, local); 1686 kit_cg_push_int(cg, 42, ctx->i32_ty); 1687 kit_cg_store(cg, mem); 1688 } 1689 1690 static void exercise_cg_memory_mismatch_diags(KitCompiler* c, 1691 KitCgTypeId i32_ty, 1692 KitCgTypeId i64_ty, 1693 KitCgTypeId rec_ty) { 1694 BadStoreCtx ctx; 1695 ctx.c = c; 1696 ctx.i32_ty = i32_ty; 1697 ctx.i64_ty = i64_ty; 1698 ctx.rec_ty = rec_ty; 1699 1700 /* Scalar store at offset 0 into an aggregate lvalue is now a field-store 1701 * under the EA model (see doc/INDIRECT.md), so no diagnostic fires. */ 1702 (void)run_bad_scalar_access_to_aggregate; 1703 EXPECT(expect_panic_contains(c, run_bad_store_value_size, &ctx, 1704 "store value type/size mismatch"), 1705 "store size mismatch should diagnose clearly, got '%s'", 1706 g_u.last_diag); 1707 } 1708 1709 static void exercise_compile_session_two_deltas(KitCompiler* c) { 1710 KitCompileSessionOptions sopts; 1711 KitCompileSession* s = NULL; 1712 KitAsmCompileOptions aopts; 1713 KitSourceInput in; 1714 KitObjBuilder* ob1 = NULL; 1715 KitObjBuilder* ob2 = NULL; 1716 static const uint8_t empty[] = ""; 1717 1718 memset(&sopts, 0, sizeof(sopts)); 1719 memset(&aopts, 0, sizeof(aopts)); 1720 sopts.lang = KIT_LANG_ASM; 1721 sopts.compile.language_options = &aopts; 1722 memset(&in, 0, sizeof(in)); 1723 in.name = KIT_SLICE_LIT("<api-session-asm>"); 1724 in.bytes.data = empty; 1725 in.bytes.len = 0; 1726 in.lang = KIT_LANG_ASM; 1727 1728 EXPECT(kit_compile_session_new(c, &sopts, &s) == KIT_OK && s, 1729 "compile session new failed"); 1730 if (!s) return; 1731 EXPECT(kit_compile_session_compile(s, &in, &ob1) == KIT_OK && ob1, 1732 "compile session first delta failed"); 1733 EXPECT(kit_compile_session_compile(s, &in, &ob2) == KIT_OK && ob2, 1734 "compile session second delta failed"); 1735 kit_obj_builder_free(ob1); 1736 kit_obj_builder_free(ob2); 1737 kit_compile_session_free(s); 1738 } 1739 1740 static void exercise_cg_begin_end_two_objects(KitCompiler* c) { 1741 KitCg* cg = NULL; 1742 KitObjBuilder* ob1 = NULL; 1743 KitObjBuilder* ob2 = NULL; 1744 KitCodeOptions opts; 1745 1746 memset(&opts, 0, sizeof(opts)); 1747 ob1 = new_obj(c); 1748 ob2 = new_obj(c); 1749 EXPECT(ob1 && ob2, "obj builder allocation failed for cg begin/end session"); 1750 EXPECT(kit_cg_new(c, &cg) == KIT_OK && cg, "cg session new failed"); 1751 if (cg && ob1) { 1752 EXPECT(kit_cg_begin(cg, ob1, &opts) == KIT_OK, 1753 "cg begin first object failed"); 1754 EXPECT(kit_cg_finish(cg, NULL) == KIT_OK, "cg finish first object failed"); 1755 EXPECT(kit_cg_detach(cg) == KIT_OK, "cg detach first object failed"); 1756 } 1757 if (cg && ob2) { 1758 EXPECT(kit_cg_begin(cg, ob2, &opts) == KIT_OK, 1759 "cg begin second object failed"); 1760 EXPECT(kit_cg_finish(cg, NULL) == KIT_OK, "cg finish second object failed"); 1761 EXPECT(kit_cg_detach(cg) == KIT_OK, "cg detach second object failed"); 1762 } 1763 kit_cg_free(cg); 1764 kit_obj_builder_free(ob1); 1765 kit_obj_builder_free(ob2); 1766 } 1767 1768 static void exercise_cg_free_does_not_finish(KitCompiler* c, 1769 KitCgTypeId i32_ty) { 1770 KitCodeOptions opts; 1771 KitCgUnitOptions unit_opts; 1772 KitObjBuilder* ob = NULL; 1773 KitCg* cg = NULL; 1774 KitCgFuncSig sig; 1775 KitCgDecl decl; 1776 KitCgSym sym; 1777 1778 memset(&opts, 0, sizeof opts); 1779 opts.opt_level = 1; 1780 ob = new_obj(c); 1781 EXPECT(ob != NULL, "no-finish obj builder allocation failed"); 1782 if (!ob) return; 1783 EXPECT(kit_cg_new(c, &cg) == KIT_OK && cg, "no-finish cg new failed"); 1784 if (!cg) { 1785 kit_obj_builder_free(ob); 1786 return; 1787 } 1788 EXPECT(kit_cg_begin(cg, ob, &opts) == KIT_OK, "no-finish cg begin failed"); 1789 memset(&unit_opts, 0, sizeof unit_opts); 1790 unit_opts.source_name = KIT_SLICE_LIT("cg_free_does_not_finish.c"); 1791 EXPECT(kit_cg_begin_unit(cg, &unit_opts) == KIT_OK, 1792 "no-finish begin unit failed"); 1793 1794 memset(&sig, 0, sizeof sig); 1795 { 1796 KitCgFuncResult result; 1797 memset(&result, 0, sizeof result); 1798 result.type = i32_ty; 1799 sig.result = result; 1800 sig.call_conv = KIT_CG_CC_TARGET_C; 1801 1802 memset(&decl, 0, sizeof decl); 1803 decl.kind = KIT_CG_DECL_FUNC; 1804 decl.linkage_name = 1805 kit_sym_intern(c, KIT_SLICE_LIT("cg_free_does_not_finish")); 1806 decl.display_name = decl.linkage_name; 1807 decl.type = kit_cg_type_func(c, sig); 1808 decl.sym.bind = KIT_SB_GLOBAL; 1809 decl.sym.visibility = KIT_CG_VIS_DEFAULT; 1810 sym = kit_cg_decl(cg, decl); 1811 } 1812 EXPECT(sym != KIT_CG_SYM_NONE, "no-finish decl failed"); 1813 kit_cg_func_begin(cg, sym); 1814 kit_cg_push_int(cg, 42, i32_ty); 1815 kit_cg_ret(cg); 1816 kit_cg_func_end(cg); 1817 EXPECT(kit_cg_end_unit(cg) == KIT_OK, "no-finish end unit failed"); 1818 1819 kit_cg_free(cg); 1820 EXPECT(kit_obj_builder_finalize(ob) == KIT_OK, 1821 "no-finish explicit object finalize failed"); 1822 EXPECT(text_size(c, ob) == 0, 1823 "kit_cg_free must not lower optimized IR into the object"); 1824 kit_obj_builder_free(ob); 1825 } 1826 1827 int main(void) { 1828 KitTargetSpec target; 1829 KitCompiler* c; 1830 KitCgTypeId void_ty; 1831 KitCgTypeId i8_ty; 1832 KitCgTypeId i32_ty; 1833 KitCgTypeId i64_ty; 1834 KitCgTypeId f64_ty; 1835 KitCgTypeId va_list_ty; 1836 KitCgTypeId ptr_i32; 1837 KitCgTypeId array_i32; 1838 KitCgTypeId huge_array_a; 1839 KitCgTypeId huge_array_b; 1840 KitCgFuncParam params[2]; 1841 KitCgFuncSig sig; 1842 KitCgTypeId fn; 1843 KitCgTypeInfo info; 1844 KitCgTypeId rec; 1845 KitCgTypeId rec_ex; 1846 KitCgTypeId rec_decl; 1847 KitCgTypeId rec_ptr; 1848 KitCgTypeId rec_self_ptr; 1849 KitCgTypeId rec_bad; 1850 KitCgTypeId enm; 1851 KitCgRecordDesc rdesc; 1852 KitCgFieldDesc fields[2]; 1853 const KitCgRecordLayout* rlayout; 1854 KitCgFieldLayout field_out; 1855 KitCgEnumValue vals[2]; 1856 uint64_t field_off; 1857 1858 kit_unit_init(&g_u); 1859 target = kit_unit_target(KIT_ARCH_ARM_64, KIT_OS_LINUX, KIT_OBJ_ELF); 1860 1861 c = NULL; 1862 if (kit_unit_compiler_new(&g_u, target, &c) != KIT_OK || !c) { 1863 fprintf(stderr, "compiler_new failed\n"); 1864 return 2; 1865 } 1866 1867 void_ty = kit_cg_type_builtin(c, KIT_CG_BUILTIN_VOID); 1868 i8_ty = kit_cg_type_builtin(c, KIT_CG_BUILTIN_I8); 1869 i32_ty = kit_cg_type_builtin(c, KIT_CG_BUILTIN_I32); 1870 i64_ty = kit_cg_type_builtin(c, KIT_CG_BUILTIN_I64); 1871 f64_ty = kit_cg_type_builtin(c, KIT_CG_BUILTIN_F64); 1872 va_list_ty = kit_cg_type_builtin(c, KIT_CG_BUILTIN_VARARG_STATE); 1873 EXPECT(void_ty != KIT_CG_TYPE_NONE, "void builtin id is none"); 1874 EXPECT(i8_ty != KIT_CG_TYPE_NONE, "i8 builtin id is none"); 1875 EXPECT(i32_ty != KIT_CG_TYPE_NONE, "i32 builtin id is none"); 1876 EXPECT(f64_ty != KIT_CG_TYPE_NONE, "f64 builtin id is none"); 1877 EXPECT(va_list_ty != KIT_CG_TYPE_NONE, "va_list builtin id is none"); 1878 EXPECT(void_ty != i32_ty && i32_ty != f64_ty, "builtin ids collide"); 1879 EXPECT(void_ty == 1u, "void builtin should be first direct id"); 1880 EXPECT(i8_ty == (KitCgTypeId)KIT_CG_BUILTIN_I8 + 1u, 1881 "builtin id should be direct enum+1"); 1882 EXPECT(!kit_cg_type_is_void(c, KIT_CG_TYPE_NONE), 1883 "invalid type id must not masquerade as void"); 1884 EXPECT(kit_cg_type_is_void(c, void_ty), "void builtin predicate failed"); 1885 EXPECT(!kit_cg_type_is_sized(c, void_ty), "void should not be sized"); 1886 1887 ptr_i32 = kit_cg_type_ptr(c, i32_ty, 0); 1888 array_i32 = kit_cg_type_array(c, i32_ty, 4); 1889 EXPECT(ptr_i32 != KIT_CG_TYPE_NONE, "ptr type failed"); 1890 EXPECT(array_i32 != KIT_CG_TYPE_NONE, "array type failed"); 1891 EXPECT(kit_cg_type_ptr(c, i32_ty, 0) == ptr_i32, 1892 "ptr type id should be interned"); 1893 EXPECT(kit_cg_type_array(c, i32_ty, 4) == array_i32, 1894 "array type id should be interned"); 1895 EXPECT(kit_cg_type_ptr(c, KIT_CG_TYPE_NONE, 0) == KIT_CG_TYPE_NONE, 1896 "invalid pointer pointee should fail"); 1897 EXPECT(kit_cg_type_size(c, ptr_i32) == 8, "ptr size mismatch"); 1898 EXPECT(kit_cg_type_align(c, ptr_i32) == 8, "ptr align mismatch"); 1899 EXPECT(kit_cg_type_ptr_pointee(c, ptr_i32) == i32_ty, "ptr pointee mismatch"); 1900 EXPECT(kit_cg_type_array_elem(c, array_i32) == i32_ty, "array elem mismatch"); 1901 EXPECT(kit_cg_type_array_count(c, array_i32) == 4, "array count mismatch"); 1902 huge_array_a = kit_cg_type_array(c, i32_ty, (uint64_t)UINT32_MAX + 1u); 1903 huge_array_b = kit_cg_type_array(c, i32_ty, 1); 1904 EXPECT(huge_array_a == KIT_CG_TYPE_NONE, 1905 "out-of-range array object should be rejected"); 1906 EXPECT(huge_array_b != KIT_CG_TYPE_NONE, 1907 "small array after huge rejection should still work"); 1908 1909 EXPECT(kit_cg_type_resolve_alias(c, i32_ty) == i32_ty, 1910 "storage identity should resolve to itself"); 1911 EXPECT(kit_cg_type_info(c, i32_ty, &info) == KIT_OK, "i32 info failed"); 1912 EXPECT(info.kind == KIT_CG_TYPE_INT && info.storage_id == i32_ty && 1913 info.layout.valid && 1914 info.layout.storage_kind == KIT_CG_STORAGE_INT && 1915 info.layout.scalar_width == 32, 1916 "i32 info identity/layout mismatch"); 1917 EXPECT(kit_cg_type_info(c, ptr_i32, &info) == KIT_OK, "ptr info failed"); 1918 EXPECT(info.kind == KIT_CG_TYPE_PTR && info.storage_id == ptr_i32, 1919 "ptr info should keep storage identity"); 1920 EXPECT(kit_cg_type_same_storage(c, i32_ty, i32_ty), 1921 "type should share storage with itself"); 1922 EXPECT(!kit_cg_type_same_storage(c, ptr_i32, i32_ty), 1923 "unrelated types should not share storage"); 1924 1925 memset(fields, 0, sizeof fields); 1926 fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("a")); 1927 fields[0].type = i32_ty; 1928 fields[0].align_override = 0; 1929 fields[1].name = kit_sym_intern(c, KIT_SLICE_LIT("b")); 1930 fields[1].type = ptr_i32; 1931 fields[1].align_override = 1; 1932 memset(&rdesc, 0, sizeof rdesc); 1933 rdesc.tag = kit_sym_intern(c, KIT_SLICE_LIT("R")); 1934 rdesc.fields = fields; 1935 rdesc.nfields = 2; 1936 rec = kit_cg_type_record(c, &rdesc); 1937 EXPECT(rec != KIT_CG_TYPE_NONE, "record type failed"); 1938 memset(&rdesc, 0, sizeof rdesc); 1939 rdesc.tag = kit_sym_intern(c, KIT_SLICE_LIT("Bad")); 1940 EXPECT(kit_cg_type_record(c, &rdesc) != KIT_CG_TYPE_NONE, 1941 "empty record type failed"); 1942 EXPECT(kit_cg_type_kind(c, rec) == KIT_CG_TYPE_RECORD, 1943 "record kind mismatch"); 1944 EXPECT(kit_cg_type_record_nfields(c, rec) == 2, 1945 "record field count mismatch"); 1946 rlayout = kit_cg_type_record_layout(c, rec); 1947 EXPECT(rlayout && rlayout->nfields > 1, "record field query failed"); 1948 field_out = rlayout->fields[1]; 1949 field_off = field_out.offset; 1950 EXPECT(field_out.name == fields[1].name && field_out.type == ptr_i32, 1951 "record field data mismatch"); 1952 EXPECT(field_off == 4, "record field offset mismatch"); 1953 1954 memset(fields, 0, sizeof fields); 1955 fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("lo")); 1956 fields[0].type = i32_ty; 1957 fields[0].flags = KIT_CG_FIELD_BITFIELD; 1958 fields[0].bit_width = 5; 1959 fields[1].name = kit_sym_intern(c, KIT_SLICE_LIT("hi")); 1960 fields[1].type = i32_ty; 1961 fields[1].flags = KIT_CG_FIELD_BITFIELD; 1962 fields[1].bit_width = 3; 1963 memset(&rdesc, 0, sizeof rdesc); 1964 rdesc.tag = kit_sym_intern(c, KIT_SLICE_LIT("BF")); 1965 rdesc.fields = fields; 1966 rdesc.nfields = 2; 1967 rec_ex = kit_cg_type_record(c, &rdesc); 1968 EXPECT(rec_ex != KIT_CG_TYPE_NONE, "bit-field record type failed"); 1969 EXPECT(kit_cg_type_size(c, rec_ex) == 4, "bit-field record size mismatch"); 1970 rlayout = kit_cg_type_record_layout(c, rec_ex); 1971 EXPECT(rlayout && rlayout->nfields > 1, "bit-field record query failed"); 1972 field_out = rlayout->fields[1]; 1973 field_off = field_out.offset; 1974 EXPECT(field_off == 0 && field_out.bit_offset == 5 && 1975 field_out.bit_width == 3 && field_out.bit_storage_size == 4, 1976 "bit-field metadata mismatch"); 1977 1978 memset(fields, 0, sizeof fields); 1979 fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("a")); 1980 fields[0].type = i32_ty; 1981 fields[1].name = kit_sym_intern(c, KIT_SLICE_LIT("b")); 1982 fields[1].type = ptr_i32; 1983 fields[1].align_override = 1; 1984 memset(&rdesc, 0, sizeof rdesc); 1985 rdesc.tag = kit_sym_intern(c, KIT_SLICE_LIT("U")); 1986 rdesc.fields = fields; 1987 rdesc.nfields = 2; 1988 rdesc.is_union = 1; 1989 rdesc.align_override = 16; 1990 rec_ex = kit_cg_type_record(c, &rdesc); 1991 EXPECT(rec_ex != KIT_CG_TYPE_NONE, "record desc type failed"); 1992 EXPECT(kit_cg_type_size(c, rec_ex) == 16, "record desc size mismatch"); 1993 EXPECT(kit_cg_type_align(c, rec_ex) == 16, "record desc align mismatch"); 1994 rlayout = kit_cg_type_record_layout(c, rec_ex); 1995 EXPECT(rlayout && rlayout->nfields > 1, "record desc field query failed"); 1996 field_out = rlayout->fields[1]; 1997 field_off = field_out.offset; 1998 EXPECT(field_off == 0, "union field offset mismatch"); 1999 2000 rec_decl = 2001 kit_cg_type_record_decl(c, kit_sym_intern(c, KIT_SLICE_LIT("Node")), 0); 2002 EXPECT(rec_decl != KIT_CG_TYPE_NONE, "record decl failed"); 2003 EXPECT(kit_cg_type_kind(c, rec_decl) == KIT_CG_TYPE_RECORD, 2004 "record decl kind mismatch"); 2005 EXPECT(!kit_cg_type_is_complete(c, rec_decl), 2006 "fresh record decl should be incomplete"); 2007 EXPECT(!kit_cg_type_is_sized(c, rec_decl), 2008 "fresh record decl should be unsized"); 2009 EXPECT(kit_cg_type_record_layout(c, rec_decl) == NULL, 2010 "incomplete record should not expose fields"); 2011 rec_ptr = kit_cg_type_ptr(c, rec_decl, 0); 2012 EXPECT(rec_ptr != KIT_CG_TYPE_NONE, 2013 "pointer to incomplete record should be legal"); 2014 EXPECT(kit_cg_type_array(c, rec_decl, 1) == KIT_CG_TYPE_NONE, 2015 "array of incomplete record should fail"); 2016 memset(fields, 0, sizeof fields); 2017 fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("next")); 2018 fields[0].type = rec_ptr; 2019 memset(&rdesc, 0, sizeof rdesc); 2020 rdesc.tag = kit_cg_type_record_tag(c, rec_decl); 2021 rdesc.fields = fields; 2022 rdesc.nfields = 1; 2023 EXPECT(kit_cg_type_record_complete(c, rec_decl, &rdesc) == KIT_OK, 2024 "record completion with self pointer failed"); 2025 EXPECT(kit_cg_type_is_complete(c, rec_decl), 2026 "completed record should be complete"); 2027 EXPECT(kit_cg_type_is_sized(c, rec_decl), "completed record should be sized"); 2028 EXPECT(kit_cg_type_record_complete(c, rec_decl, &rdesc) == KIT_INVALID, 2029 "record completion should be one-shot"); 2030 2031 rec_bad = kit_cg_type_record_decl( 2032 c, kit_sym_intern(c, KIT_SLICE_LIT("ByValueSelf")), 0); 2033 memset(fields, 0, sizeof fields); 2034 fields[0].name = kit_sym_intern(c, KIT_SLICE_LIT("self")); 2035 fields[0].type = rec_bad; 2036 memset(&rdesc, 0, sizeof rdesc); 2037 rdesc.tag = kit_cg_type_record_tag(c, rec_bad); 2038 rdesc.fields = fields; 2039 rdesc.nfields = 1; 2040 EXPECT(kit_cg_type_record_complete(c, rec_bad, &rdesc) == KIT_INVALID, 2041 "recursive by-value record should fail"); 2042 rec_self_ptr = kit_cg_type_ptr(c, rec_bad, 0); 2043 EXPECT(rec_self_ptr != KIT_CG_TYPE_NONE, 2044 "pointer to failed incomplete record should still be legal"); 2045 2046 vals[0].name = kit_sym_intern(c, KIT_SLICE_LIT("A")); 2047 vals[0].value = 1; 2048 vals[1].name = kit_sym_intern(c, KIT_SLICE_LIT("B")); 2049 vals[1].value = 2; 2050 enm = kit_cg_type_enum(c, kit_sym_intern(c, KIT_SLICE_LIT("E")), 2051 KIT_CG_TYPE_NONE, vals, 2); 2052 EXPECT(enm != KIT_CG_TYPE_NONE, "enum type failed"); 2053 /* Enumerators must be preserved so debug info can emit DW_TAG_enumerator 2054 * children rather than collapsing the enum to a bare integer. */ 2055 EXPECT(kit_cg_type_enum_nvalues(c, enm) == 2, 2056 "enum should preserve its enumerator count"); 2057 { 2058 KitCgEnumValue ev; 2059 EXPECT(kit_cg_type_enum_value(c, enm, 1, &ev) == KIT_OK && 2060 ev.name == vals[1].name && ev.value == 2, 2061 "enum should preserve enumerator name/value pairs"); 2062 } 2063 /* An enum with an explicit integer underlying type must construct and retain 2064 * that operational base exactly. Source spellings now travel through the 2065 * debug type channel rather than wrapper type ids. */ 2066 { 2067 KitCgTypeId enm_u = kit_cg_type_enum( 2068 c, kit_sym_intern(c, KIT_SLICE_LIT("EU")), i8_ty, vals, 2); 2069 EXPECT(enm_u != KIT_CG_TYPE_NONE, 2070 "enum over an explicit integer underlying type should construct"); 2071 EXPECT(kit_cg_type_enum_base(c, enm_u) == i8_ty, 2072 "enum should retain its explicit underlying type id"); 2073 EXPECT(kit_cg_type_int_width(c, enm_u) == 8, 2074 "enum width should follow its explicit underlying type"); 2075 } 2076 2077 memset(params, 0, sizeof(params)); 2078 params[0].type = i32_ty; 2079 params[1].type = ptr_i32; 2080 memset(&sig, 0, sizeof(sig)); 2081 KitCgFuncResult sig_result; 2082 memset(&sig_result, 0, sizeof sig_result); 2083 sig_result.type = i64_ty; 2084 sig.result = sig_result; 2085 sig.params = params; 2086 sig.nparams = 2; 2087 sig.abi_variadic = 1; 2088 sig.call_conv = KIT_CG_CC_TARGET_C; 2089 fn = kit_cg_type_func(c, sig); 2090 EXPECT(fn != KIT_CG_TYPE_NONE, "function type failed"); 2091 EXPECT(kit_cg_type_func(c, sig) == fn, "function type id should be interned"); 2092 EXPECT(kit_cg_type_func_result(c, fn).type == i64_ty, 2093 "function return mismatch"); 2094 EXPECT(kit_cg_type_func_nparams(c, fn) == 2, "function param count mismatch"); 2095 EXPECT(kit_cg_type_func_param(c, fn, 1).type == ptr_i32, 2096 "function param mismatch"); 2097 memset(&sig, 0, sizeof sig); 2098 sig.result.type = void_ty; 2099 fn = kit_cg_type_func(c, sig); 2100 EXPECT(fn != KIT_CG_TYPE_NONE, "void function type failed"); 2101 EXPECT(kit_cg_type_func_result(c, fn).type == void_ty, 2102 "void function result should use void builtin"); 2103 EXPECT(!kit_cg_func_result_has_value(c, kit_cg_type_func_result(c, fn)), 2104 "void function should not have a value result"); 2105 memset(&sig, 0, sizeof sig); 2106 EXPECT(kit_cg_type_func(c, sig) == KIT_CG_TYPE_NONE, 2107 "function result NONE should be rejected"); 2108 sig.nparams = 70000; 2109 EXPECT(kit_cg_type_func(c, sig) == KIT_CG_TYPE_NONE, 2110 "oversized function param list should fail"); 2111 2112 exercise_cg_handles(c, i32_ty, 0); 2113 exercise_cg_handles(c, i32_ty, 1); 2114 exercise_cg_scalar_local(c, i32_ty, 0); 2115 exercise_cg_scalar_local(c, i32_ty, 1); 2116 exercise_cg_late_local_addr(c, i32_ty, 0); 2117 exercise_cg_late_local_addr(c, i32_ty, 1); 2118 exercise_cg_data_entsize(c, i8_ty); 2119 exercise_cg_debug_global_object(c, i32_ty); 2120 exercise_cg_literal_folds(c, i32_ty); 2121 exercise_cg_constfold_phases(c, i32_ty, i8_ty); 2122 exercise_cg_memop_constfold_shape(c, i32_ty, i64_ty, ptr_i32); 2123 exercise_cg_slot_lang_facts(c, i32_ty); 2124 exercise_cg_field_at_store_keep(c, i32_ty, rec); 2125 exercise_cg_memory_mismatch_diags(c, i32_ty, i64_ty, rec); 2126 exercise_compile_session_two_deltas(c); 2127 exercise_cg_begin_end_two_objects(c); 2128 exercise_cg_free_does_not_finish(c, i32_ty); 2129 2130 kit_compiler_free(c); 2131 kit_unit_summary(&g_u, "cg_api_test"); 2132 return kit_unit_status(&g_u); 2133 }