#ifndef __SCC_IR_DEF_H__ #define __SCC_IR_DEF_H__ #include typedef struct scc_ir_node scc_ir_node_t; typedef SCC_VEC(scc_ir_node_t) scc_ir_node_vec_t; typedef enum scc_ir_type_tag { SCC_IR_TYPE_VOID, SCC_IR_TYPE_I32, SCC_IR_TYPE_PTR, SCC_IR_TYPE_ARRAY, SCC_IR_TYPE_FUNC, } scc_ir_type_tag_t; typedef struct scc_ir_type scc_ir_type_t; typedef SCC_VEC(scc_ir_type_t) scc_ir_type_vec_t; struct scc_ir_type { scc_ir_type_tag_t tag; union { struct { const scc_ir_type_t *base; usize len; } array; struct { const scc_ir_type_t *base; } pointer; struct { scc_ir_type_vec_t params; const scc_ir_type_t *ret_type; } function; } data; }; typedef struct scc_ir_bblock { const char *label; scc_ir_node_vec_t instrs; // ir_arr_t used_by; } scc_ir_bblock_t; // basic block typedef SCC_VEC(scc_ir_bblock_t) scc_ir_bblock_vec_t; typedef struct { const char *name; scc_ir_type_t *type; scc_ir_node_vec_t params; scc_ir_bblock_vec_t bblocks; } scc_ir_func_t; typedef SCC_VEC(scc_ir_func_t) scc_ir_func_vec_t; typedef enum scc_ir_node_tag { SCC_IR_NODE_NULL, SCC_IR_NODE_CONST_INT, SCC_IR_NODE_ALLOC, SCC_IR_NODE_LOAD, SCC_IR_NODE_STORE, SCC_IR_NODE_GET_PTR, SCC_IR_NODE_OP, SCC_IR_NODE_BRANCH, SCC_IR_NODE_JUMP, SCC_IR_NODE_CALL, SCC_IR_NODE_RET, } scc_ir_node_tag_t; typedef enum { /// Empty op for init or nop IR_OP_EMPTY, /// Not equal to. IR_OP_NEQ, /// Equal to. IR_OP_EQ, /// Greater than. IR_OP_GT, /// Less than. IR_OP_LT, /// Greater than or equal to. IR_OP_GE, /// Less than or equal to. IR_OP_LE, /// Addition. IR_OP_ADD, /// Subtraction. IR_OP_SUB, /// Multiplication. IR_OP_MUL, /// Division. IR_OP_DIV, /// Modulo. IR_OP_MOD, /// Bitwise AND. IR_OP_AND, /// Bitwise OR. IR_OP_OR, /// Bitwise XOR. IR_OP_XOR, /// Bitwise NOT. IR_OP_NOT, /// Shift left logical. IR_OP_SHL, /// Shift right logical. IR_OP_SHR, /// Shift right arithmetic. IR_OP_SAR, } scc_ir_op_type_t; struct scc_ir_node { const scc_ir_type_t *type; const char *name; scc_ir_node_vec_t used_by; scc_ir_node_tag_t tag; union { union { i8 int8; i16 int16; i32 int32; i64 int64; // TODO int128 i8 int_any[4]; } const_int; union { u8 uint8; u16 uint16; u32 uint32; u64 uint64; // TODO uint128; u8 uint_any[4]; } const_uint; // aggregate; // func_arg_ref; // block_arg_ref; // global_alloc; struct { scc_ir_node_t *target; } load; struct { scc_ir_node_t *target; scc_ir_node_t *value; } store; struct { scc_ir_node_t *src_addr; scc_ir_node_t *index; } get_ptr; struct { scc_ir_node_t *src_addr; scc_ir_node_t *index; } get_elem_ptr; struct { scc_ir_op_type_t op; scc_ir_node_t *lhs; scc_ir_node_t *rhs; } op; struct { scc_ir_node_t *cond; scc_ir_bblock_t *true_bblock; scc_ir_bblock_t *false_bblock; } branch; struct { scc_ir_bblock_t *target_bblock; } jump; struct { scc_ir_func_t *callee; scc_ir_node_vec_t args; } call; struct { scc_ir_node_t *ret_val; } ret; } data; }; typedef struct { scc_ir_node_vec_t global_vals; scc_ir_func_vec_t funcs; scc_ir_func_vec_t extern_funcs; } ir_cprog_t; #endif /* __SCC_IR_DEF_H__ */