cg.c (25145B)
1 #include <string.h> 2 3 #include "parse/parse_priv.h" 4 5 #define C_CG_VALUE_LVALUE ((uint16_t)1u) 6 #define C_CG_VALUE_MODIFIABLE ((uint16_t)2u) 7 #define C_CG_VALUE_BITFIELD ((uint16_t)4u) 8 #define C_CG_VALUE_NULL_PTR_CONST ((uint16_t)8u) 9 #define C_CG_VALUE_REGISTER ((uint16_t)16u) 10 11 KitCgTypeId c_cg_tid(Parser* p, const Type* ty) { 12 return type_cg_id_in_pool(p->c, p->pool, ty); 13 } 14 15 static uint16_t c_cg_lvalue_flags_for_type(const Type* ty) { 16 uint16_t flags = C_CG_VALUE_LVALUE; 17 if (ty && !(ty->qual & Q_CONST) && ty->kind != TY_ARRAY && 18 ty->kind != TY_FUNC && ty->kind != TY_VOID) { 19 flags |= C_CG_VALUE_MODIFIABLE; 20 } 21 return flags; 22 } 23 24 /* Resolve the operational CG type for a value-stack slot. A complete recorded 25 * type is authoritative. A missing type, or an incomplete nominal record left 26 * by dereferencing a pointer, crosses back through the frontend lang_type so a 27 * by-value operation sees the completed layout. kit_cg_slot_cg_type reads the 28 * slot's id directly (no struct copy). */ 29 static KitCgTypeId c_cg_slot_cg_id(Parser* p, u32 depth) { 30 const Type* lang_ty = 31 (const Type*)kit_cg_slot_lang_type(p->cg, depth); 32 KitCgTypeId cg = kit_cg_slot_cg_type(p->cg, depth); 33 KitCgTypeId resolved; 34 if (cg && kit_cg_type_is_complete(p->c, cg)) return cg; 35 36 /* A pointer to a record needs only its nominal CG declaration. Dereferencing 37 * that pointer therefore leaves an incomplete record id on the value stack, 38 * even when the C record itself is complete. A later by-value operation 39 * (load/store/aggregate copy) must cross back through the language type so 40 * its field layout is installed before the memory operation captures a byte 41 * count. Returning the recorded id unconditionally made the first 42 * `*dst = *src` for such a type a zero-byte copy. */ 43 resolved = lang_ty ? c_cg_tid(p, lang_ty) : KIT_CG_TYPE_NONE; 44 return resolved ? resolved : cg; 45 } 46 47 static KitCgTypeId c_cg_top_cg_id(Parser* p) { return c_cg_slot_cg_id(p, 0); } 48 49 static KitCgTypeId c_cg_top2_cg_id(Parser* p) { return c_cg_slot_cg_id(p, 1); } 50 51 static KitCgMemAccess c_cg_mem_id(Parser* p, KitCgTypeId id, const Type* ty) { 52 KitCgMemAccess m; 53 (void)p; 54 memset(&m, 0, sizeof m); 55 m.type = id; 56 if (ty && (ty->qual & Q_VOLATILE)) m.flags |= KIT_CG_MEM_VOLATILE; 57 if (type_is_int(ty) && c_cg_type_is_signed(ty)) 58 m.flags |= KIT_CG_MEM_SOURCE_SIGNED; 59 return m; 60 } 61 62 KitCgMemAccess c_cg_mem(Parser* p, const Type* ty) { 63 return c_cg_mem_id(p, c_cg_tid(p, ty), ty); 64 } 65 66 const Type* c_cg_top_type(Parser* p) { 67 return (const Type*)kit_cg_slot_lang_type(p->cg, 0); 68 } 69 70 const Type* c_cg_top2_type(Parser* p) { 71 return (const Type*)kit_cg_slot_lang_type(p->cg, 1); 72 } 73 74 void c_cg_retag_top(Parser* p, const Type* ty) { 75 kit_cg_retag_top(p->cg, ty, 0); 76 } 77 78 void c_cg_retag_at(Parser* p, u32 depth, const Type* ty, uint16_t flags) { 79 kit_cg_retag_at(p->cg, depth, ty, flags); 80 } 81 82 void c_cg_retag_keep_flags(Parser* p, u32 depth, const Type* ty) { 83 kit_cg_retag_at(p->cg, depth, ty, kit_cg_slot_lang_flags(p->cg, depth)); 84 } 85 86 void c_cg_dup(Parser* p) { kit_cg_dup(p->cg); } 87 88 void c_cg_swap(Parser* p) { kit_cg_swap(p->cg); } 89 90 void c_cg_drop(Parser* p) { kit_cg_drop(p->cg); } 91 92 void c_cg_reclaim_temps(Parser* p) { kit_cg_reclaim_temps(p->cg); } 93 94 uint32_t c_cg_stack_depth(Parser* p) { return kit_cg_stack_depth(p->cg); } 95 96 void c_cg_drop_to_depth(Parser* p, uint32_t depth) { 97 while (kit_cg_stack_depth(p->cg) > depth) kit_cg_drop(p->cg); 98 } 99 100 int c_cg_top_is_bitfield(Parser* p) { 101 return (kit_cg_slot_lang_flags(p->cg, 0) & C_CG_VALUE_BITFIELD) != 0; 102 } 103 104 void c_cg_set_top_bitfield(Parser* p) { 105 kit_cg_set_top_flags(p->cg, C_CG_VALUE_BITFIELD, 0); 106 } 107 108 int c_cg_top_is_register(Parser* p) { 109 return (kit_cg_slot_lang_flags(p->cg, 0) & C_CG_VALUE_REGISTER) != 0; 110 } 111 112 void c_cg_set_top_register(Parser* p) { 113 kit_cg_set_top_flags(p->cg, C_CG_VALUE_REGISTER, 0); 114 } 115 116 int c_cg_top_is_lvalue(Parser* p) { 117 return (kit_cg_slot_lang_flags(p->cg, 0) & C_CG_VALUE_LVALUE) != 0; 118 } 119 120 int c_cg_top_is_modifiable_lvalue(Parser* p) { 121 uint16_t flags = kit_cg_slot_lang_flags(p->cg, 0); 122 return (flags & (C_CG_VALUE_LVALUE | C_CG_VALUE_MODIFIABLE)) == 123 (C_CG_VALUE_LVALUE | C_CG_VALUE_MODIFIABLE); 124 } 125 126 int c_cg_top_is_null_ptr_const(Parser* p) { 127 return (kit_cg_slot_lang_flags(p->cg, 0) & C_CG_VALUE_NULL_PTR_CONST) != 0; 128 } 129 130 void c_cg_set_top_lvalue(Parser* p) { 131 const Type* ty = c_cg_top_type(p); 132 kit_cg_retag_top(p->cg, ty, c_cg_lvalue_flags_for_type(ty)); 133 } 134 135 int c_cg_emit_enabled(Parser* p) { return p && p->suppress_codegen == 0; } 136 137 void c_cg_codegen_suppress_push(Parser* p) { 138 if (!p) return; 139 ++p->suppress_codegen; 140 kit_cg_unevaluated_push(p->cg); 141 } 142 143 void c_cg_codegen_suppress_pop(Parser* p) { 144 if (!p) return; 145 if (!p->suppress_codegen) 146 perr(p, "internal parser codegen suppression underflow"); 147 kit_cg_unevaluated_pop(p->cg); 148 --p->suppress_codegen; 149 } 150 151 int c_cg_type_is_fp(const Type* ty) { 152 return ty && type_kind_is_fp((TypeKind)ty->kind); 153 } 154 155 int c_cg_type_is_signed(const Type* ty) { return type_is_signed_integer(ty); } 156 157 KitCgIntBinOp c_cg_int_binop(BinOp op) { 158 switch (op) { 159 case BO_IADD: 160 return KIT_CG_INT_ADD; 161 case BO_ISUB: 162 return KIT_CG_INT_SUB; 163 case BO_IMUL: 164 return KIT_CG_INT_MUL; 165 case BO_SDIV: 166 return KIT_CG_INT_SDIV; 167 case BO_UDIV: 168 return KIT_CG_INT_UDIV; 169 case BO_SREM: 170 return KIT_CG_INT_SREM; 171 case BO_UREM: 172 return KIT_CG_INT_UREM; 173 case BO_AND: 174 return KIT_CG_INT_AND; 175 case BO_OR: 176 return KIT_CG_INT_OR; 177 case BO_XOR: 178 return KIT_CG_INT_XOR; 179 case BO_SHL: 180 return KIT_CG_INT_SHL; 181 case BO_SHR_S: 182 return KIT_CG_INT_ASHR; 183 case BO_SHR_U: 184 return KIT_CG_INT_LSHR; 185 default: 186 return KIT_CG_INT_ADD; 187 } 188 } 189 190 KitCgFpBinOp c_cg_fp_binop(BinOp op) { 191 switch (op) { 192 case BO_FADD: 193 return KIT_CG_FP_ADD; 194 case BO_FSUB: 195 return KIT_CG_FP_SUB; 196 case BO_FMUL: 197 return KIT_CG_FP_MUL; 198 case BO_FDIV: 199 return KIT_CG_FP_DIV; 200 default: 201 return KIT_CG_FP_ADD; 202 } 203 } 204 205 KitCgIntCmpOp c_cg_int_cmp(CmpOp op) { 206 switch (op) { 207 case CMP_EQ: 208 return KIT_CG_INT_EQ; 209 case CMP_NE: 210 return KIT_CG_INT_NE; 211 case CMP_LT_S: 212 return KIT_CG_INT_LT_S; 213 case CMP_LE_S: 214 return KIT_CG_INT_LE_S; 215 case CMP_GT_S: 216 return KIT_CG_INT_GT_S; 217 case CMP_GE_S: 218 return KIT_CG_INT_GE_S; 219 case CMP_LT_U: 220 return KIT_CG_INT_LT_U; 221 case CMP_LE_U: 222 return KIT_CG_INT_LE_U; 223 case CMP_GT_U: 224 return KIT_CG_INT_GT_U; 225 case CMP_GE_U: 226 return KIT_CG_INT_GE_U; 227 default: 228 return KIT_CG_INT_EQ; 229 } 230 } 231 232 KitCgFpCmpOp c_cg_fp_cmp(CmpOp op) { 233 switch (op) { 234 case CMP_EQ: 235 return KIT_CG_FP_OEQ; 236 case CMP_NE: 237 return KIT_CG_FP_UNE; 238 case CMP_LT_F: 239 case CMP_OLT_F: 240 return KIT_CG_FP_OLT; 241 case CMP_LE_F: 242 case CMP_OLE_F: 243 return KIT_CG_FP_OLE; 244 case CMP_GT_F: 245 case CMP_OGT_F: 246 return KIT_CG_FP_OGT; 247 case CMP_GE_F: 248 case CMP_OGE_F: 249 return KIT_CG_FP_OGE; 250 case CMP_OEQ_F: 251 return KIT_CG_FP_OEQ; 252 case CMP_ONE_F: 253 return KIT_CG_FP_ONE; 254 case CMP_UEQ_F: 255 return KIT_CG_FP_UEQ; 256 case CMP_UNE_F: 257 return KIT_CG_FP_UNE; 258 case CMP_ULT_F: 259 return KIT_CG_FP_ULT; 260 case CMP_ULE_F: 261 return KIT_CG_FP_ULE; 262 case CMP_UGT_F: 263 return KIT_CG_FP_UGT; 264 case CMP_UGE_F: 265 return KIT_CG_FP_UGE; 266 default: 267 return KIT_CG_FP_OEQ; 268 } 269 } 270 271 KitCgAtomicOp c_cg_atomic_op(AtomicOp op) { 272 switch (op) { 273 case AO_XCHG: 274 return KIT_CG_ATOMIC_XCHG; 275 case AO_ADD: 276 return KIT_CG_ATOMIC_ADD; 277 case AO_SUB: 278 return KIT_CG_ATOMIC_SUB; 279 case AO_AND: 280 return KIT_CG_ATOMIC_AND; 281 case AO_OR: 282 return KIT_CG_ATOMIC_OR; 283 case AO_XOR: 284 return KIT_CG_ATOMIC_XOR; 285 case AO_NAND: 286 return KIT_CG_ATOMIC_NAND; 287 } 288 return KIT_CG_ATOMIC_XCHG; 289 } 290 291 KitCgMemOrder c_cg_mem_order(MemOrder ord) { return (KitCgMemOrder)ord; } 292 293 static int c_cg_slot_is_volatile(const FrameSlotDesc* fsd) { 294 return fsd && ((fsd->flags & FSF_VOLATILE) || 295 (fsd->type && (fsd->type->qual & Q_VOLATILE))); 296 } 297 298 FrameSlot c_cg_local(Parser* p, const FrameSlotDesc* fsd) { 299 KitCgLocalAttrs attrs; 300 if (!c_cg_emit_enabled(p)) return FRAME_SLOT_NONE; 301 memset(&attrs, 0, sizeof attrs); 302 attrs.name = fsd->name; 303 attrs.align = fsd->align; 304 attrs.debug_type = type_cg_debug_in_pool(p->cg, p->c, p->pool, fsd->type); 305 if (c_cg_slot_is_volatile(fsd)) attrs.flags |= KIT_CG_LOCAL_MEMORY_REQUIRED; 306 return kit_cg_local(p->cg, c_cg_tid(p, fsd->type), attrs); 307 } 308 309 FrameSlot c_cg_param_slot(Parser* p, u32 index, const FrameSlotDesc* fsd) { 310 KitCgLocalAttrs attrs; 311 if (!c_cg_emit_enabled(p)) return FRAME_SLOT_NONE; 312 memset(&attrs, 0, sizeof attrs); 313 attrs.name = fsd->name; 314 attrs.align = fsd->align; 315 attrs.debug_type = type_cg_debug_in_pool(p->cg, p->c, p->pool, fsd->type); 316 if (c_cg_slot_is_volatile(fsd)) attrs.flags |= KIT_CG_LOCAL_MEMORY_REQUIRED; 317 return kit_cg_param(p->cg, index, c_cg_tid(p, fsd->type), attrs); 318 } 319 320 void c_cg_param(Parser* p, const CGParamDesc* pd) { 321 (void)p; 322 (void)pd; 323 } 324 325 void c_cg_func_begin(Parser* p, const CGFuncDesc* fd) { 326 KitCgFuncAttrs attrs; 327 if (!c_cg_emit_enabled(p)) return; 328 memset(&attrs, 0, sizeof attrs); 329 attrs.inline_policy = fd->inline_policy; 330 attrs.debug_type = type_cg_debug_in_pool(p->cg, p->c, p->pool, fd->fn_type); 331 if (fd->flags & CGFD_NORETURN) attrs.flags |= KIT_CG_FUNC_NORETURN; 332 kit_cg_func_begin_attrs(p->cg, fd->sym, attrs); 333 } 334 335 void c_cg_func_end(Parser* p) { 336 if (c_cg_emit_enabled(p)) kit_cg_func_end(p->cg); 337 } 338 339 void c_cg_set_loc(Parser* p, SrcLoc loc) { kit_cg_set_loc(p->cg, loc); } 340 341 static void c_cg_push_dummy_place(Parser* p, const Type* ty) { 342 const Type* base = ty ? ty : type_void(p->pool); 343 const Type* ptr_ty = type_ptr(p->pool, base); 344 kit_cg_push_null(p->cg, c_cg_tid(p, ptr_ty)); 345 kit_cg_deref(p->cg, 0); 346 } 347 348 void c_cg_push_int(Parser* p, i64 v, const Type* ty) { 349 uint16_t flags = 0; 350 kit_cg_push_int(p->cg, (uint64_t)v, c_cg_tid(p, ty)); 351 if (v == 0) flags |= C_CG_VALUE_NULL_PTR_CONST; 352 kit_cg_retag_top(p->cg, ty, flags); 353 } 354 355 void c_cg_push_float(Parser* p, double v, const Type* ty) { 356 kit_cg_push_float(p->cg, v, c_cg_tid(p, ty)); 357 kit_cg_retag_top(p->cg, ty, 0); 358 } 359 360 void c_cg_push_local_typed(Parser* p, FrameSlot s, const Type* ty) { 361 if (s == FRAME_SLOT_NONE) { 362 c_cg_push_dummy_place(p, ty); 363 } else { 364 kit_cg_push_local(p->cg, s); 365 } 366 kit_cg_retag_top(p->cg, ty, c_cg_lvalue_flags_for_type(ty)); 367 } 368 369 void c_cg_push_global(Parser* p, ObjSymId sym, const Type* ty) { 370 if (sym == OBJ_SYM_NONE) { 371 c_cg_push_dummy_place(p, ty); 372 } else if (ty && ty->kind == TY_FUNC) { 373 kit_cg_push_symbol_addr(p->cg, sym, 0); 374 } else { 375 kit_cg_push_symbol_addr(p->cg, sym, 0); 376 kit_cg_deref(p->cg, 0); 377 } 378 kit_cg_retag_top(p->cg, ty, c_cg_lvalue_flags_for_type(ty)); 379 } 380 381 void c_cg_load(Parser* p) { 382 const Type* ty = c_cg_top_type(p); 383 kit_cg_load(p->cg, c_cg_mem_id(p, c_cg_top_cg_id(p), ty)); 384 kit_cg_retag_top(p->cg, ty, 0); 385 } 386 387 void c_cg_addr(Parser* p) { 388 const Type* ty = c_cg_top_type(p); 389 const Type* ptr_ty = type_ptr(p->pool, ty ? ty : type_void(p->pool)); 390 if (!(ty && ty->kind == TY_FUNC)) kit_cg_addr(p->cg); 391 kit_cg_retag_top(p->cg, ptr_ty, 0); 392 } 393 394 void c_cg_push_label_addr(Parser* p, CGLabel label) { 395 const Type* vp = type_ptr(p->pool, type_void(p->pool)); 396 kit_cg_push_label_addr(p->cg, label, c_cg_tid(p, vp)); 397 kit_cg_retag_top(p->cg, vp, 0); 398 } 399 400 void c_cg_computed_goto(Parser* p, const CGLabel* targets, u32 ntargets) { 401 kit_cg_computed_goto(p->cg, targets, ntargets); 402 } 403 404 CGLabel c_cg_label_new(Parser* p) { 405 if (!c_cg_emit_enabled(p)) return (CGLabel)1; 406 return kit_cg_label_new(p->cg); 407 } 408 409 void c_cg_label_place(Parser* p, CGLabel l) { 410 if (c_cg_emit_enabled(p)) kit_cg_label_place(p->cg, l); 411 } 412 413 void c_cg_jump(Parser* p, CGLabel l) { 414 if (c_cg_emit_enabled(p)) kit_cg_jump(p->cg, l); 415 } 416 417 void c_cg_branch_true(Parser* p, CGLabel l) { 418 if (!c_cg_emit_enabled(p)) { 419 if (c_cg_stack_depth(p)) c_cg_drop(p); 420 return; 421 } 422 kit_cg_branch_true(p->cg, l); 423 } 424 425 void c_cg_branch_false(Parser* p, CGLabel l) { 426 if (!c_cg_emit_enabled(p)) { 427 if (c_cg_stack_depth(p)) c_cg_drop(p); 428 return; 429 } 430 kit_cg_branch_false(p->cg, l); 431 } 432 433 void c_cg_store(Parser* p) { 434 const Type* lv_ty = c_cg_top2_type(p); 435 const Type* rv_ty = c_cg_top_type(p); 436 const Type* mem_ty = lv_ty; 437 KitCgTypeId mem_cg = c_cg_top2_cg_id(p); 438 if (rv_ty && type_is_ptr(rv_ty) && (!lv_ty || !type_is_ptr(lv_ty))) { 439 mem_ty = rv_ty; 440 mem_cg = c_cg_top_cg_id(p); 441 } 442 kit_cg_store_keep(p->cg, c_cg_mem_id(p, mem_cg, mem_ty)); 443 kit_cg_retag_top(p->cg, rv_ty, 0); 444 } 445 446 void c_cg_store_void(Parser* p) { 447 const Type* lv_ty = c_cg_top2_type(p); 448 const Type* rv_ty = c_cg_top_type(p); 449 const Type* mem_ty = lv_ty; 450 KitCgTypeId mem_cg = c_cg_top2_cg_id(p); 451 if (rv_ty && type_is_ptr(rv_ty) && (!lv_ty || !type_is_ptr(lv_ty))) { 452 mem_ty = rv_ty; 453 mem_cg = c_cg_top_cg_id(p); 454 } 455 kit_cg_store(p->cg, c_cg_mem_id(p, mem_cg, mem_ty)); 456 } 457 458 void c_cg_deref(Parser* p, const Type* pointee) { 459 const Type* ptr_ty = c_cg_top_type(p); 460 if (pointee && pointee->kind == TY_FUNC) { 461 c_cg_retag_top(p, pointee); 462 c_cg_set_top_lvalue(p); 463 return; 464 } 465 if (ptr_ty && ptr_ty->kind == TY_PTR && ptr_ty->ptr.pointee != pointee) { 466 const Type* want_ptr_ty = type_ptr(p->pool, pointee); 467 kit_cg_bitcast(p->cg, c_cg_tid(p, want_ptr_ty)); 468 c_cg_retag_top(p, want_ptr_ty); 469 } 470 kit_cg_deref(p->cg, 0); 471 kit_cg_retag_top(p->cg, pointee, c_cg_lvalue_flags_for_type(pointee)); 472 } 473 474 void c_cg_lv_member(Parser* p, i64 byte_offset, const Type* field_ty, 475 u16 bf_offset, u16 bf_width, u32 bf_storage_size) { 476 const Type* base_ty = c_cg_top_type(p); 477 int was_lvalue = c_cg_top_is_lvalue(p); 478 int base_is_rvalue_agg = 479 !was_lvalue && base_ty && 480 (base_ty->kind == TY_STRUCT || base_ty->kind == TY_UNION); 481 uint16_t flags = 0; 482 kit_cg_field_at(p->cg, byte_offset, c_cg_tid(p, field_ty)); 483 if (bf_width) { 484 kit_cg_field_bits(p->cg, bf_offset, bf_width, bf_storage_size, 485 c_cg_type_is_signed(field_ty)); 486 } 487 if (was_lvalue) 488 flags = c_cg_lvalue_flags_for_type(field_ty); 489 else if (base_is_rvalue_agg) 490 flags = C_CG_VALUE_LVALUE; 491 if (bf_width) flags |= C_CG_VALUE_BITFIELD; 492 kit_cg_retag_top(p->cg, field_ty, flags); 493 } 494 495 void c_cg_lv_subscript(Parser* p, u32 elem_size, const Type* elem_ty) { 496 (void)elem_size; 497 kit_cg_elem(p->cg, 0); 498 kit_cg_retag_top(p->cg, elem_ty, c_cg_lvalue_flags_for_type(elem_ty)); 499 } 500 501 void c_cg_decay_array(Parser* p, const Type* arr_ty) { 502 const Type* ptr_ty = type_ptr(p->pool, arr_ty->arr.elem); 503 kit_cg_addr(p->cg); 504 kit_cg_bitcast(p->cg, c_cg_tid(p, ptr_ty)); 505 kit_cg_retag_top(p->cg, ptr_ty, 0); 506 } 507 508 void c_cg_binop(Parser* p, BinOp op) { 509 const Type* result = c_cg_top2_type(p); 510 if (op == BO_FADD || op == BO_FSUB || op == BO_FMUL || op == BO_FDIV) 511 kit_cg_fp_binop(p->cg, c_cg_fp_binop(op), KIT_CG_FP_NONE); 512 else 513 kit_cg_int_binop(p->cg, c_cg_int_binop(op), KIT_CG_INTOP_NONE); 514 kit_cg_retag_top(p->cg, result, 0); 515 } 516 517 void c_cg_unop(Parser* p, UnOp op) { 518 const Type* ty = c_cg_top_type(p); 519 if (op == UO_NEG && c_cg_type_is_fp(ty)) { 520 kit_cg_fp_unop(p->cg, KIT_CG_FP_NEG, KIT_CG_FP_NONE); 521 } else { 522 KitCgIntUnOp iop = op == UO_NOT ? KIT_CG_INT_NOT 523 : op == UO_BNOT ? KIT_CG_INT_BNOT 524 : KIT_CG_INT_NEG; 525 kit_cg_int_unop(p->cg, iop, KIT_CG_INTOP_NONE); 526 } 527 kit_cg_retag_top(p->cg, ty, 0); 528 } 529 530 void c_cg_cmp(Parser* p, CmpOp op) { 531 if (op >= CMP_LT_F || 532 ((op == CMP_EQ || op == CMP_NE) && c_cg_type_is_fp(c_cg_top_type(p)))) 533 kit_cg_fp_cmp(p->cg, c_cg_fp_cmp(op)); 534 else 535 kit_cg_int_cmp(p->cg, c_cg_int_cmp(op)); 536 kit_cg_retag_top(p->cg, type_prim(p->pool, TY_INT), 0); 537 } 538 539 void c_cg_convert(Parser* p, const Type* dst) { 540 const Type* src = c_cg_top_type(p); 541 KitCgTypeId src_id = c_cg_top_cg_id(p); 542 KitCgTypeId id = c_cg_tid(p, dst); 543 u32 ss = (u32)kit_cg_type_size(p->c, src_id); 544 u32 ds = (u32)kit_cg_type_size(p->c, id); 545 int si = type_is_int(src) || type_is_ptr(src); 546 int di = type_is_int(dst) || type_is_ptr(dst); 547 int sf = c_cg_type_is_fp(src); 548 int df = c_cg_type_is_fp(dst); 549 if (src == dst) return; 550 if (src && (src->kind == TY_STRUCT || src->kind == TY_UNION)) { 551 c_cg_retag_keep_flags(p, 0, dst); 552 return; 553 } 554 if (dst->kind == TY_BOOL && src->kind != TY_BOOL) { 555 if (sf) { 556 kit_cg_push_float(p->cg, 0.0, src_id); 557 kit_cg_fp_cmp(p->cg, KIT_CG_FP_UNE); 558 } else { 559 kit_cg_push_int(p->cg, 0, src_id); 560 kit_cg_int_cmp(p->cg, KIT_CG_INT_NE); 561 } 562 kit_cg_trunc(p->cg, id); 563 kit_cg_retag_top(p->cg, dst, 0); 564 return; 565 } 566 if (type_is_ptr(src) && type_is_ptr(dst)) { 567 kit_cg_bitcast(p->cg, id); 568 } else if (si && di) { 569 if (ds < ss) 570 kit_cg_trunc(p->cg, id); 571 else if (ds > ss && type_is_int(src) && c_cg_type_is_signed(src)) 572 kit_cg_sext(p->cg, id); 573 else if (ds > ss) 574 kit_cg_zext(p->cg, id); 575 else if (type_is_ptr(src) != type_is_ptr(dst)) 576 kit_cg_bitcast(p->cg, id); 577 } else if (type_is_int(src) && df) { 578 if (c_cg_type_is_signed(src)) 579 kit_cg_sint_to_float(p->cg, id, KIT_CG_ROUND_DEFAULT); 580 else 581 kit_cg_uint_to_float(p->cg, id, KIT_CG_ROUND_DEFAULT); 582 } else if (sf && type_is_int(dst)) { 583 if (c_cg_type_is_signed(dst)) 584 kit_cg_float_to_sint(p->cg, id, KIT_CG_ROUND_DEFAULT); 585 else 586 kit_cg_float_to_uint(p->cg, id, KIT_CG_ROUND_DEFAULT); 587 } else if (sf && df) { 588 if (ds > ss) 589 kit_cg_fpext(p->cg, id); 590 else if (ds < ss) 591 kit_cg_fptrunc(p->cg, id); 592 } else { 593 kit_cg_bitcast(p->cg, id); 594 } 595 kit_cg_retag_top(p->cg, dst, 0); 596 } 597 598 static void c_cg_emit_inc_step(Parser* p, const Type* ty, BinOp op, 599 const Type* step_ty, u32 step) { 600 if (c_cg_type_is_fp(ty)) { 601 c_cg_push_float(p, 1.0, ty); 602 c_cg_binop(p, op == BO_ISUB ? BO_FSUB : BO_FADD); 603 } else { 604 i64 amount = (ty && ty->kind == TY_PTR) ? (i64)step : 1; 605 c_cg_push_int(p, amount, step_ty); 606 c_cg_binop(p, op); 607 } 608 } 609 610 void c_cg_inc_dec(Parser* p, BinOp op, int post) { 611 const Type* ty = c_cg_top_type(p); 612 const Type* step_ty = ty; 613 u32 step = 1; 614 KitCgMemAccess access = c_cg_mem_id(p, c_cg_top_cg_id(p), ty); 615 if (ty && ty->kind == TY_PTR) { 616 const Type* pointee = ty->ptr.pointee; 617 if (pointee && pointee->kind == TY_VOID) 618 perr(p, "pointer arithmetic on void pointer"); 619 step = c_abi_sizeof(p->abi, p->pool, pointee); 620 step_ty = c_abi_ptrdiff_type(p->abi, p->pool); 621 } 622 c_cg_dup(p); 623 c_cg_load(p); 624 if (post) { 625 FrameSlotDesc fsd; 626 FrameSlot tmp; 627 memset(&fsd, 0, sizeof fsd); 628 fsd.type = ty; 629 fsd.size = c_abi_sizeof(p->abi, p->pool, ty); 630 fsd.align = c_abi_alignof(p->abi, p->pool, ty); 631 fsd.kind = FS_LOCAL; 632 tmp = c_cg_local(p, &fsd); 633 c_cg_push_local_typed(p, tmp, ty); 634 c_cg_swap(p); 635 c_cg_store_void(p); 636 c_cg_push_local_typed(p, tmp, ty); 637 c_cg_load(p); 638 c_cg_emit_inc_step(p, ty, op, step_ty, step); 639 kit_cg_store(p->cg, access); 640 c_cg_push_local_typed(p, tmp, ty); 641 c_cg_load(p); 642 } else { 643 c_cg_emit_inc_step(p, ty, op, step_ty, step); 644 kit_cg_store_keep(p->cg, access); 645 kit_cg_retag_top(p->cg, ty, 0); 646 } 647 } 648 649 void c_cg_call(Parser* p, u32 nargs, const Type* fn_type) { 650 kit_cg_call_default(p->cg, nargs, c_cg_tid(p, fn_type)); 651 if (fn_type && fn_type->kind == TY_FUNC && fn_type->fn.ret->kind != TY_VOID) 652 kit_cg_retag_top(p->cg, fn_type->fn.ret, 0); 653 } 654 655 void c_cg_call_symbol(Parser* p, KitCgSym sym, u32 nargs, const Type* fn_type) { 656 KitCgCallAttrs attrs; 657 memset(&attrs, 0, sizeof attrs); 658 kit_cg_call_symbol(p->cg, sym, nargs, attrs); 659 if (fn_type && fn_type->kind == TY_FUNC && fn_type->fn.ret->kind != TY_VOID) 660 kit_cg_retag_top(p->cg, fn_type->fn.ret, 0); 661 } 662 663 void c_cg_ret(Parser* p, int has_value) { 664 if (p->stack_protector_scan) { 665 if (has_value) c_cg_drop(p); 666 return; 667 } 668 if (has_value) { 669 kit_cg_ret(p->cg); 670 } else if (c_cg_emit_enabled(p)) { 671 if (p->cur_func_ret && p->cur_func_ret->kind != TY_VOID) 672 kit_cg_unreachable(p->cg); 673 else 674 kit_cg_ret(p->cg); 675 } 676 } 677 678 void c_cg_alloca(Parser* p) { 679 const Type* vp = type_ptr(p->pool, type_void(p->pool)); 680 c_stack_protector_enable(p); 681 kit_cg_alloca(p->cg, 16, c_cg_tid(p, vp)); 682 kit_cg_retag_top(p->cg, vp, 0); 683 } 684 685 void c_cg_va_arg(Parser* p, const Type* ty) { 686 kit_cg_vararg_next(p->cg, c_cg_tid(p, ty)); 687 kit_cg_retag_top(p->cg, ty, 0); 688 } 689 690 void c_cg_va_start(Parser* p) { kit_cg_vararg_start(p->cg); } 691 692 void c_cg_va_end(Parser* p) { kit_cg_vararg_end(p->cg); } 693 694 void c_cg_va_copy(Parser* p) { kit_cg_vararg_copy(p->cg); } 695 696 void c_cg_atomic_load(Parser* p, MemOrder ord) { 697 const Type* pty = c_cg_top_type(p); 698 const Type* ty = (pty && pty->kind == TY_PTR) ? pty->ptr.pointee : pty; 699 kit_cg_atomic_load(p->cg, c_cg_mem(p, ty), c_cg_mem_order(ord)); 700 kit_cg_retag_top(p->cg, ty, 0); 701 } 702 703 void c_cg_atomic_store(Parser* p, MemOrder ord) { 704 const Type* pty = c_cg_top2_type(p); 705 const Type* ty = (pty && pty->kind == TY_PTR) ? pty->ptr.pointee : pty; 706 kit_cg_atomic_store(p->cg, c_cg_mem(p, ty), c_cg_mem_order(ord)); 707 } 708 709 void c_cg_atomic_rmw(Parser* p, AtomicOp op, MemOrder ord) { 710 const Type* pty = c_cg_top2_type(p); 711 const Type* ty = (pty && pty->kind == TY_PTR) ? pty->ptr.pointee : pty; 712 kit_cg_atomic_rmw(p->cg, c_cg_mem(p, ty), c_cg_atomic_op(op), 713 c_cg_mem_order(ord)); 714 kit_cg_retag_top(p->cg, ty, 0); 715 } 716 717 void c_cg_atomic_cas(Parser* p, MemOrder succ, MemOrder fail) { 718 const Type* ty = c_cg_top2_type(p); 719 kit_cg_atomic_cmpxchg(p->cg, c_cg_mem(p, ty), c_cg_mem_order(succ), 720 c_cg_mem_order(fail), 0); 721 c_cg_retag_at(p, 1, ty, 0); 722 c_cg_retag_top(p, type_prim(p->pool, TY_BOOL)); 723 } 724 725 void c_cg_fence(Parser* p, MemOrder ord) { 726 kit_cg_atomic_fence(p->cg, c_cg_mem_order(ord)); 727 } 728 729 void c_cg_intrinsic_unary_to_int(Parser* p, IntrinKind k) { 730 KitCgIntrinsic ck = k == INTRIN_CLZ ? KIT_CG_INTRIN_CLZ 731 : k == INTRIN_CTZ ? KIT_CG_INTRIN_CTZ 732 : KIT_CG_INTRIN_POPCOUNT; 733 const Type* ity = type_prim(p->pool, TY_INT); 734 kit_cg_intrinsic(p->cg, ck, 1, c_cg_tid(p, ity)); 735 kit_cg_retag_top(p->cg, ity, 0); 736 } 737 738 void c_cg_intrinsic_void(Parser* p, IntrinKind k) { 739 if (k == INTRIN_UNREACHABLE) { 740 kit_cg_unreachable(p->cg); 741 } else { 742 kit_cg_intrinsic(p->cg, KIT_CG_INTRIN_TRAP, 0, 743 kit_cg_type_builtin(p->c, KIT_CG_BUILTIN_VOID)); 744 } 745 } 746 747 void c_cg_syscall(Parser* p, u32 nargs, const Type* long_ty) { 748 kit_cg_intrinsic(p->cg, KIT_CG_INTRIN_SYSCALL, nargs, c_cg_tid(p, long_ty)); 749 kit_cg_retag_top(p->cg, long_ty, 0); 750 } 751 752 void c_cg_readcyclecounter(Parser* p) { 753 const Type* ull = type_prim(p->pool, TY_ULLONG); 754 kit_cg_intrinsic(p->cg, KIT_CG_INTRIN_READCYCLECOUNTER, 0, c_cg_tid(p, ull)); 755 kit_cg_retag_top(p->cg, ull, 0); 756 } 757 758 void c_cg_frame_or_return_address(Parser* p, int is_return, u32 level) { 759 const Type* void_ptr = type_ptr(p->pool, type_void(p->pool)); 760 KitCgIntrinsic intrin = 761 is_return ? KIT_CG_INTRIN_RETURN_ADDRESS : KIT_CG_INTRIN_FRAME_ADDRESS; 762 c_cg_push_int(p, (i64)level, type_prim(p->pool, TY_INT)); 763 kit_cg_intrinsic(p->cg, intrin, 1, c_cg_tid(p, void_ptr)); 764 kit_cg_retag_top(p->cg, void_ptr, 0); 765 } 766 767 void c_cg_inline_asm(Parser* p, const char* tmpl, const AsmConstraint* outs, 768 u32 nout, const AsmConstraint* ins, u32 nin, 769 const Sym* clobbers, u32 nclob, u32 flags) { 770 KitCgInlineAsm a; 771 KitCgAsmOperand* o = NULL; 772 KitCgAsmOperand* in = NULL; 773 KitSym* cl = NULL; 774 memset(&a, 0, sizeof a); 775 a.tmpl = kit_sym_intern(p->c, kit_slice_cstr(tmpl ? tmpl : "")); 776 if (nout) { 777 o = arena_zarray(p->pool->arena, KitCgAsmOperand, nout); 778 for (u32 i = 0; i < nout; ++i) { 779 o[i].constraint = 780 kit_sym_intern(p->c, kit_slice_cstr(outs[i].str ? outs[i].str : "")); 781 o[i].name = outs[i].name; 782 o[i].type = c_cg_tid(p, outs[i].type); 783 o[i].reg = outs[i].reg; 784 o[i].dir = KIT_CG_ASM_OUT; 785 } 786 } 787 if (nin) { 788 in = arena_zarray(p->pool->arena, KitCgAsmOperand, nin); 789 for (u32 i = 0; i < nin; ++i) { 790 in[i].constraint = 791 kit_sym_intern(p->c, kit_slice_cstr(ins[i].str ? ins[i].str : "")); 792 in[i].name = ins[i].name; 793 in[i].type = c_cg_tid(p, ins[i].type); 794 in[i].reg = ins[i].reg; 795 in[i].dir = (ins[i].dir == ASM_INOUT) ? KIT_CG_ASM_INOUT : KIT_CG_ASM_IN; 796 } 797 } 798 if (nclob) { 799 cl = arena_array(p->pool->arena, KitSym, nclob); 800 for (u32 i = 0; i < nclob; ++i) cl[i] = clobbers[i]; 801 } 802 a.outputs = o; 803 a.noutputs = nout; 804 a.inputs = in; 805 a.ninputs = nin; 806 a.clobbers = cl; 807 a.nclobbers = nclob; 808 a.flags = flags; 809 kit_cg_inline_asm(p->cg, a); 810 for (u32 i = 0; i < nout; ++i) { 811 u32 depth = nout - 1u - i; 812 c_cg_retag_at(p, depth, outs[i].type, 0); 813 } 814 }