#ifndef __SPL_IR_H__ #define __SPL_IR_H__ #include "../stage0/include/utils.h" /* clang-format off */ #define SPL_IR_FN_TABLE \ X(arith.add, V0, SPL_IR_ARITH_ADD) \ X(arith.sub, V0, SPL_IR_ARITH_SUB) \ X(arith.mul, V0, SPL_IR_ARITH_MUL) \ X(arith.div, V0, SPL_IR_ARITH_DIV) \ X(arith.rem, V0, SPL_IR_ARITH_REM) \ X(arith.neg, V0, SPL_IR_ARITH_NEG) \ X(arith.abs, V0, SPL_IR_ARITH_ABS) \ X(arith.and, V0, SPL_IR_ARITH_AND) \ X(arith.or, V0, SPL_IR_ARITH_OR) \ X(arith.xor, V0, SPL_IR_ARITH_XOR) \ X(arith.shl, V0, SPL_IR_ARITH_SHL) \ X(arith.shr, V0, SPL_IR_ARITH_SHR) \ X(arith.not, V0, SPL_IR_ARITH_NOT) \ X(cmp.eq, V0, SPL_IR_CMP_EQ) \ X(cmp.ne, V0, SPL_IR_CMP_NE) \ X(cmp.lt, V0, SPL_IR_CMP_LT) \ X(cmp.le, V0, SPL_IR_CMP_LE) \ X(cmp.gt, V0, SPL_IR_CMP_GT) \ X(cmp.ge, V0, SPL_IR_CMP_GE) \ X(cast.trunc, V0, SPL_IR_CAST_TRUNC) \ X(cast.zext, V0, SPL_IR_CAST_ZEXT) \ X(cast.sext, V0, SPL_IR_CAST_SEXT) \ X(cast.fext, V0, SPL_IR_CAST_FEXT) \ X(cast.ftrunc, V0, SPL_IR_CAST_FTRUNC) \ X(cast.bitcast, V0, SPL_IR_CAST_BITCAST) \ X(cast.ptr2int, V0, SPL_IR_CAST_PTR2INT) \ X(cast.int2ptr, V0, SPL_IR_CAST_INT2PTR) \ X(cast.bool2int, V0, SPL_IR_CAST_BOOL2INT) \ X(case.int2float, V0, SPL_IR_CASE_INT2FLOAT) \ X(case.float2int, V0, SPL_IR_CASE_FLOAT2INT) \ X(mem.alloca, V0, SPL_IR_MEM_ALLOCA) \ X(mem.load, V0, SPL_IR_MEM_LOAD) \ X(mem.store, V0, SPL_IR_MEM_STORE) \ X(mem.offset, V0, SPL_IR_MEM_OFFSET) \ X(mem.copy, V0, SPL_IR_MEM_COPY) \ X(mem.set, V0, SPL_IR_MEM_SET) \ X(mem.fence, V0, SPL_IR_MEM_FENCE) \ X(type.const, V0, SPL_IR_TYPE_CONST) \ X(type.bitsizeof, V0, SPL_IR_TYPE_BITSIZEOF) \ X(type.sizeof, V0, SPL_IR_TYPE_SIZEOF) \ X(type.alignof, V0, SPL_IR_TYPE_ALIGNOF) \ X(type.offsetof, V0, SPL_IR_TYPE_OFFSETOF) \ X(type.field_count, V0, SPL_IR_TYPE_FIELD_COUNT) \ X(agg.construct, V0, SPL_IR_AGG_CONSTRUCT) \ X(agg.extract, V0, SPL_IR_AGG_EXTRACT) \ X(agg.insert, V0, SPL_IR_AGG_INSERT) \ X(atomic.load, V0, SPL_IR_ATOMIC_LOAD) \ X(atomic.store, V0, SPL_IR_ATOMIC_STORE) \ X(atomic.rmw_add, V0, SPL_IR_ATOMIC_RMW_ADD) \ X(atomic.rmw_sub, V0, SPL_IR_ATOMIC_RMW_SUB) \ X(atomic.rmw_and, V0, SPL_IR_ATOMIC_RMW_AND) \ X(atomic.rmw_or, V0, SPL_IR_ATOMIC_RMW_OR) \ X(atomic.rmw_xor, V0, SPL_IR_ATOMIC_RMW_XOR) \ X(atomic.rmw_xchg, V0, SPL_IR_ATOMIC_RMW_XCHG) \ X(atomic.cmpxchg, V0, SPL_IR_ATOMIC_CMPXCHG) \ X(control.select, V0, SPL_IR_CONTROL_SELECT) \ X(control.br, V0, SPL_IR_CONTROL_BR) \ X(control.jmp, V0, SPL_IR_CONTROL_JMP) \ X(control.call, V0, SPL_IR_CONTROL_CALL) \ X(control.ret, V0, SPL_IR_CONTROL_RET) \ X(control.unreachable, V0, SPL_IR_CONTROL_UNREACHABLE) \ X(control.trap, V0, SPL_IR_CONTROL_TRAP) \ X(dbg.breakpoint, V0, SPL_IR_DBG_BREAKPOINT) \ X(dbg.declare, V0, SPL_IR_DBG_DECLARE) /* clang-format on */ typedef struct { enum { } kind; } spl_ir_node_t; typedef VEC(spl_ir_node_t) spl_ir_node_vec_t; typedef usize spl_ir_node_ref_t; typedef VEC(spl_ir_node_ref_t) spl_ir_node_ref_vec_t; typedef struct { const char *name; spl_ir_node_vec_t nodes; spl_ir_node_ref_vec_t labels; } spl_ir_func_t; typedef VEC(spl_ir_func_t) spl_ir_func_vec_t; typedef struct { spl_ir_func_vec_t funcs; } spl_ir_t; void spl_ir_init(spl_ir_t *ir); void spl_ir_drop(spl_ir_t *ir); void spl_ir_dump(spl_ir_t *ir); #endif /* __SPL_IR_H__ */