cg.h (7249B)
1 #ifndef KIT_PARSE_CG_H 2 #define KIT_PARSE_CG_H 3 4 /* cg.h — the C parser <-> codegen seam. 5 * 6 * Declares C-semantic helpers implemented in cg.c. The expression stack is the 7 * public KitCg stack; C type/category facts live in KitCg slot metadata and 8 * are read back through the KitCg slot inspection helpers. */ 9 10 #include <kit/cg.h> 11 12 #include "c_support.h" 13 #include "type/type.h" 14 15 typedef KitCg CG; 16 typedef KitCgLabel CGLabel; 17 typedef KitCgLocal FrameSlot; 18 19 #define FRAME_SLOT_NONE KIT_CG_LOCAL_NONE 20 #define OBJ_GROUP_NONE 0u 21 22 typedef enum BinOp { 23 BO_IADD, 24 BO_ISUB, 25 BO_IMUL, 26 BO_SDIV, 27 BO_UDIV, 28 BO_SREM, 29 BO_UREM, 30 BO_FADD, 31 BO_FSUB, 32 BO_FMUL, 33 BO_FDIV, 34 BO_AND, 35 BO_OR, 36 BO_XOR, 37 BO_SHL, 38 BO_SHR_S, 39 BO_SHR_U, 40 } BinOp; 41 42 typedef enum UnOp { 43 UO_NEG, 44 UO_NOT, 45 UO_BNOT, 46 } UnOp; 47 48 /* Compare markers used by the C parser. The integer block plus the four 49 * relational FP markers (CMP_LT_F..CMP_GE_F) cover the bare C operators; the 50 * latter map to the *ordered* FP predicates in c_cg_fp_cmp. The trailing 51 * ordered/unordered block mirrors the global CmpOp / public KitCgFpCmpOp so 52 * the C99 comparison builtins (islessgreater -> CMP_ONE_F) and any 53 * negation-driven unordered duals are reachable from the frontend 1:1. */ 54 typedef enum CmpOp { 55 CMP_EQ, 56 CMP_NE, 57 CMP_LT_S, 58 CMP_LE_S, 59 CMP_GT_S, 60 CMP_GE_S, 61 CMP_LT_U, 62 CMP_LE_U, 63 CMP_GT_U, 64 CMP_GE_U, 65 /* Relational FP operator markers (bare `< <= > >=` on floats) -> ordered. */ 66 CMP_LT_F, 67 CMP_LE_F, 68 CMP_GT_F, 69 CMP_GE_F, 70 /* Ordered FP relationals (NaN -> false). */ 71 CMP_OEQ_F, 72 CMP_ONE_F, 73 CMP_OLT_F, 74 CMP_OLE_F, 75 CMP_OGT_F, 76 CMP_OGE_F, 77 /* Unordered FP relationals (NaN -> true). */ 78 CMP_UEQ_F, 79 CMP_UNE_F, 80 CMP_ULT_F, 81 CMP_ULE_F, 82 CMP_UGT_F, 83 CMP_UGE_F, 84 } CmpOp; 85 86 typedef enum AtomicOp { 87 AO_XCHG, 88 AO_ADD, 89 AO_SUB, 90 AO_AND, 91 AO_OR, 92 AO_XOR, 93 AO_NAND, 94 } AtomicOp; 95 96 typedef enum MemOrder { 97 MO_RELAXED, 98 MO_CONSUME, 99 MO_ACQUIRE, 100 MO_RELEASE, 101 MO_ACQ_REL, 102 MO_SEQ_CST, 103 } MemOrder; 104 105 typedef enum IntrinKind { 106 INTRIN_NONE = 0, 107 INTRIN_POPCOUNT, 108 INTRIN_CTZ, 109 INTRIN_CLZ, 110 INTRIN_MEMCPY, 111 INTRIN_MEMMOVE, 112 INTRIN_MEMSET, 113 INTRIN_PREFETCH, 114 INTRIN_ASSUME_ALIGNED, 115 INTRIN_EXPECT, 116 INTRIN_UNREACHABLE, 117 INTRIN_TRAP, 118 INTRIN_SETJMP, 119 INTRIN_LONGJMP, 120 INTRIN_SADD_OVERFLOW, 121 INTRIN_UADD_OVERFLOW, 122 INTRIN_SSUB_OVERFLOW, 123 INTRIN_USUB_OVERFLOW, 124 INTRIN_SMUL_OVERFLOW, 125 INTRIN_UMUL_OVERFLOW, 126 } IntrinKind; 127 128 typedef enum AsmDir { ASM_IN, ASM_OUT, ASM_INOUT } AsmDir; 129 130 typedef struct AsmConstraint { 131 const char* str; 132 Sym name; 133 const Type* type; 134 Sym reg; /* hard-register name for a GNU local register variable; 0 = none */ 135 u8 dir; 136 u8 pad[3]; 137 } AsmConstraint; 138 139 typedef enum FrameSlotKind { 140 FS_LOCAL, 141 FS_PARAM, 142 FS_SPILL, 143 FS_SRET, 144 FS_ALLOCA, 145 } FrameSlotKind; 146 147 typedef enum FrameSlotFlag { 148 FSF_NONE = 0, 149 FSF_ADDR_TAKEN = 1u << 0, 150 FSF_VOLATILE = 1u << 1, 151 } FrameSlotFlag; 152 153 typedef struct FrameSlotDesc { 154 const Type* type; 155 Sym name; 156 SrcLoc loc; 157 u32 size; 158 u32 align; 159 u8 kind; 160 u8 pad; 161 u16 flags; 162 } FrameSlotDesc; 163 164 typedef struct CGParamDesc { 165 u32 index; 166 Sym name; 167 const Type* type; 168 FrameSlot slot; 169 const void* abi; 170 const void* incoming; 171 u32 nincoming; 172 SrcLoc loc; 173 } CGParamDesc; 174 175 typedef enum CGFuncDescFlag { 176 CGFD_NONE = 0, 177 CGFD_NORETURN = 1u << 0, 178 } CGFuncDescFlag; 179 180 typedef struct CGFuncDesc { 181 ObjSymId sym; 182 ObjSecId text_section_id; 183 u32 group_id; 184 const Type* fn_type; 185 const void* abi; 186 const CGParamDesc* params; 187 u32 nparams; 188 SrcLoc loc; 189 u32 flags; 190 KitCgInlinePolicy inline_policy; 191 } CGFuncDesc; 192 193 typedef struct Parser Parser; 194 195 KitCgTypeId c_cg_tid(Parser*, const Type*); 196 KitCgMemAccess c_cg_mem(Parser*, const Type*); 197 const Type* c_cg_top_type(Parser*); 198 const Type* c_cg_top2_type(Parser*); 199 void c_cg_retag_top(Parser*, const Type*); 200 void c_cg_retag_at(Parser*, u32 depth, const Type*, uint16_t flags); 201 void c_cg_retag_keep_flags(Parser*, u32 depth, const Type*); 202 void c_cg_dup(Parser*); 203 void c_cg_swap(Parser*); 204 void c_cg_drop(Parser*); 205 void c_cg_reclaim_temps(Parser*); 206 uint32_t c_cg_stack_depth(Parser*); 207 void c_cg_drop_to_depth(Parser*, uint32_t depth); 208 int c_cg_top_is_bitfield(Parser*); 209 void c_cg_set_top_bitfield(Parser*); 210 int c_cg_top_is_register(Parser*); 211 void c_cg_set_top_register(Parser*); 212 int c_cg_top_is_lvalue(Parser*); 213 int c_cg_top_is_modifiable_lvalue(Parser*); 214 int c_cg_top_is_null_ptr_const(Parser*); 215 void c_cg_set_top_lvalue(Parser*); 216 int c_cg_emit_enabled(Parser*); 217 void c_cg_codegen_suppress_push(Parser*); 218 void c_cg_codegen_suppress_pop(Parser*); 219 220 KitCgIntBinOp c_cg_int_binop(BinOp); 221 KitCgFpBinOp c_cg_fp_binop(BinOp); 222 KitCgIntCmpOp c_cg_int_cmp(CmpOp); 223 KitCgFpCmpOp c_cg_fp_cmp(CmpOp); 224 KitCgAtomicOp c_cg_atomic_op(AtomicOp); 225 KitCgMemOrder c_cg_mem_order(MemOrder); 226 int c_cg_type_is_fp(const Type*); 227 int c_cg_type_is_signed(const Type*); 228 229 FrameSlot c_cg_local(Parser*, const FrameSlotDesc*); 230 FrameSlot c_cg_param_slot(Parser*, u32, const FrameSlotDesc*); 231 void c_cg_param(Parser*, const CGParamDesc*); 232 void c_cg_func_begin(Parser*, const CGFuncDesc*); 233 void c_cg_func_end(Parser*); 234 void c_cg_set_loc(Parser*, SrcLoc); 235 void c_cg_push_int(Parser*, i64, const Type*); 236 void c_cg_push_float(Parser*, double, const Type*); 237 void c_cg_push_local_typed(Parser*, FrameSlot, const Type*); 238 void c_cg_push_global(Parser*, ObjSymId, const Type*); 239 void c_cg_load(Parser*); 240 void c_cg_addr(Parser*); 241 void c_cg_push_label_addr(Parser*, CGLabel); 242 void c_cg_computed_goto(Parser*, const CGLabel*, u32); 243 CGLabel c_cg_label_new(Parser*); 244 void c_cg_label_place(Parser*, CGLabel); 245 void c_cg_jump(Parser*, CGLabel); 246 void c_cg_branch_true(Parser*, CGLabel); 247 void c_cg_branch_false(Parser*, CGLabel); 248 void c_cg_store(Parser*); 249 /* Store whose assignment value is discarded (replaces `c_cg_store; c_cg_drop`). 250 */ 251 void c_cg_store_void(Parser*); 252 void c_cg_deref(Parser*, const Type*); 253 void c_cg_lv_member(Parser*, i64 byte_offset, const Type* field_ty, 254 u16 bf_offset, u16 bf_width, u32 bf_storage_size); 255 void c_cg_lv_subscript(Parser*, u32 elem_size, const Type* elem_ty); 256 void c_cg_decay_array(Parser*, const Type* arr_ty); 257 258 void c_cg_binop(Parser*, BinOp); 259 void c_cg_unop(Parser*, UnOp); 260 void c_cg_cmp(Parser*, CmpOp); 261 void c_cg_convert(Parser*, const Type*); 262 void c_cg_inc_dec(Parser*, BinOp, int); 263 void c_cg_call(Parser*, u32, const Type*); 264 void c_cg_call_symbol(Parser*, KitCgSym, u32, const Type*); 265 void c_cg_ret(Parser*, int); 266 void c_cg_alloca(Parser*); 267 void c_cg_va_arg(Parser*, const Type*); 268 void c_cg_va_start(Parser*); 269 void c_cg_va_end(Parser*); 270 void c_cg_va_copy(Parser*); 271 void c_cg_atomic_load(Parser*, MemOrder); 272 void c_cg_atomic_store(Parser*, MemOrder); 273 void c_cg_atomic_rmw(Parser*, AtomicOp, MemOrder); 274 void c_cg_atomic_cas(Parser*, MemOrder, MemOrder); 275 void c_cg_fence(Parser*, MemOrder); 276 void c_cg_intrinsic_unary_to_int(Parser*, IntrinKind); 277 void c_cg_intrinsic_void(Parser*, IntrinKind); 278 void c_cg_syscall(Parser*, u32 nargs, const Type* long_ty); 279 void c_cg_frame_or_return_address(Parser*, int is_return, u32 level); 280 void c_cg_readcyclecounter(Parser*); 281 void c_cg_inline_asm(Parser*, const char*, const AsmConstraint*, u32, 282 const AsmConstraint*, u32, const Sym*, u32, u32); 283 284 #endif