kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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