diff options
| author | gingerBill <bill@gingerbill.org> | 2023-07-14 16:03:21 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-07-14 16:03:21 +0100 |
| commit | a8afcf1ca950eded2d9c45750debd287f7998d1c (patch) | |
| tree | 1b0f749dfe41ec2da6af8d8c661c3954b520c3c5 | |
| parent | 6545cc2d48553e3129ef8e925531a1ca7e03e8a6 (diff) | |
cg_emit_load/cg_emit_store
| -rw-r--r-- | src/tilde_backend.cpp | 83 | ||||
| -rw-r--r-- | src/tilde_backend.hpp | 3 | ||||
| -rw-r--r-- | src/tilde_expr.cpp | 4 | ||||
| -rw-r--r-- | src/tilde_stmt.cpp | 84 |
4 files changed, 174 insertions, 0 deletions
diff --git a/src/tilde_backend.cpp b/src/tilde_backend.cpp index 8009a7703..9b0c9105b 100644 --- a/src/tilde_backend.cpp +++ b/src/tilde_backend.cpp @@ -1,5 +1,88 @@ #include "tilde_backend.hpp" +// returns TB_TYPE_VOID if not trivially possible +gb_internal TB_DataType cg_data_type(Type *t) { + GB_ASSERT(t != nullptr); + t = core_type(t); + switch (t->kind) { + case Type_Basic: + switch (t->Basic.kind) { + case Basic_bool: return TB_TYPE_BOOL; + case Basic_b8: return TB_TYPE_BOOL; + case Basic_b16: return TB_TYPE_I16; + case Basic_b32: return TB_TYPE_I32; + case Basic_b64: return TB_TYPE_I64; + + case Basic_i8: return TB_TYPE_I8; + case Basic_u8: return TB_TYPE_I8; + case Basic_i16: return TB_TYPE_I16; + case Basic_u16: return TB_TYPE_I16; + case Basic_i32: return TB_TYPE_I32; + case Basic_u32: return TB_TYPE_I32; + case Basic_i64: return TB_TYPE_I64; + case Basic_u64: return TB_TYPE_I64; + case Basic_i128: return TB_TYPE_I128; + case Basic_u128: return TB_TYPE_I128; + + case Basic_rune: return TB_TYPE_I32; + + case Basic_f16: return TB_TYPE_I16; + case Basic_f32: return TB_TYPE_F32; + case Basic_f64: return TB_TYPE_F64; + + case Basic_int: return TB_TYPE_INTN(cast(u16)build_context.int_size); + case Basic_uint: return TB_TYPE_INTN(cast(u16)build_context.int_size); + case Basic_uintptr: return TB_TYPE_INTN(cast(u16)build_context.ptr_size); + case Basic_rawptr: return TB_TYPE_PTR; + case Basic_cstring: return TB_TYPE_PTR; + + case Basic_typeid: return TB_TYPE_INTN(cast(u16)build_context.ptr_size); + + // Endian Specific Types + case Basic_i16le: return TB_TYPE_I16; + case Basic_u16le: return TB_TYPE_I16; + case Basic_i32le: return TB_TYPE_I32; + case Basic_u32le: return TB_TYPE_I32; + case Basic_i64le: return TB_TYPE_I64; + case Basic_u64le: return TB_TYPE_I64; + case Basic_i128le: return TB_TYPE_I128; + case Basic_u128le: return TB_TYPE_I128; + + case Basic_i16be: return TB_TYPE_I16; + case Basic_u16be: return TB_TYPE_I16; + case Basic_i32be: return TB_TYPE_I32; + case Basic_u32be: return TB_TYPE_I32; + case Basic_i64be: return TB_TYPE_I64; + case Basic_u64be: return TB_TYPE_I64; + case Basic_i128be: return TB_TYPE_I128; + case Basic_u128be: return TB_TYPE_I128; + + case Basic_f16le: return TB_TYPE_I16; + case Basic_f32le: return TB_TYPE_F32; + case Basic_f64le: return TB_TYPE_F64; + + case Basic_f16be: return TB_TYPE_I16; + case Basic_f32be: return TB_TYPE_F32; + case Basic_f64be: return TB_TYPE_F64; + } + + case Type_Pointer: + case Type_MultiPointer: + case Type_Proc: + return TB_TYPE_PTR; + + case Type_BitSet: + return cg_data_type(bit_set_to_int(t)); + + case Type_RelativePointer: + return cg_data_type(t->RelativePointer.base_integer); + } + + // unknown + return {}; +} + + gb_internal cgValue cg_value(TB_Global *g, Type *type) { return cg_value((TB_Symbol *)g, type); } diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp index 48404daec..9d13a87d5 100644 --- a/src/tilde_backend.hpp +++ b/src/tilde_backend.hpp @@ -7,6 +7,9 @@ #include "tilde/tb.h" +#define TB_TYPE_I128 TB_DataType{ { TB_INT, 0, 128 } } + + #if defined(GB_SYSTEM_WINDOWS) #pragma warning(pop) #endif diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 3fa084e1a..9910801bd 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -50,6 +50,10 @@ gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) { } cgValue res = cg_build_expr_internal(p, expr); + if (res.kind == cgValue_Symbol) { + GB_ASSERT(is_type_pointer(res.type)); + res = cg_value(tb_inst_get_symbol_address(p->func, res.symbol), res.type); + } if (expr->state_flags & StateFlag_SelectorCallExpr) { // map_set(&p->selector_values, expr, res); diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index 831741559..a2a6923c4 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -96,6 +96,90 @@ gb_internal void cg_build_assignment(cgProcedure *p, Array<cgAddr> const &lhs, S } +gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_volatile=false) { + GB_ASSERT(is_type_pointer(ptr.type)); + Type *type = type_deref(ptr.type); + TB_DataType dt = cg_data_type(type); + + if (TB_IS_VOID_TYPE(dt)) { + switch (ptr.kind) { + case cgValue_Value: + return cg_lvalue_addr(ptr.node, type); + case cgValue_Addr: + GB_PANIC("NOT POSSIBLE"); + break; + case cgValue_Symbol: + return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type); + } + } + + TB_CharUnits alignment = 1; // for the time being + + TB_Node *the_ptr = nullptr; + switch (ptr.kind) { + case cgValue_Value: + the_ptr = ptr.node; + break; + case cgValue_Addr: + the_ptr = tb_inst_load(p->func, TB_TYPE_PTR, ptr.node, alignment, is_volatile); + break; + case cgValue_Symbol: + the_ptr = tb_inst_get_symbol_address(p->func, ptr.symbol); + break; + } + return cg_value(tb_inst_load(p->func, dt, the_ptr, alignment, is_volatile), type); +} + +gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src, bool is_volatile=false) { + if (dst.kind == cgValue_Addr) { + dst = cg_emit_load(p, dst, is_volatile); + } else if (dst.kind = cgValue_Symbol) { + dst = cg_value(tb_inst_get_symbol_address(p->func, dst.symbol), dst.type); + } + + GB_ASSERT(is_type_pointer(dst.type)); + Type *dst_type = type_deref(dst.type); + + GB_ASSERT_MSG(are_types_identical(dst_type, src.type), "%s vs %s", type_to_string(dst_type), type_to_string(src.type)); + + TB_DataType dt = cg_data_type(dst_type); + TB_DataType st = cg_data_type(src.type); + GB_ASSERT(dt.raw == st.raw); + + if (TB_IS_VOID_TYPE(dt)) { + // TODO(bill): needs to be memmove + GB_PANIC("todo emit store to aggregate type"); + return; + } + + TB_CharUnits alignment = 1; // for the time being + + switch (dst.kind) { + case cgValue_Value: + switch (dst.kind) { + case cgValue_Value: + tb_inst_store(p->func, dt, dst.node, src.node, alignment, is_volatile); + return; + case cgValue_Addr: + tb_inst_store(p->func, dt, dst.node, + tb_inst_load(p->func, st, src.node, alignment, is_volatile), + alignment, is_volatile); + return; + case cgValue_Symbol: + tb_inst_store(p->func, dt, dst.node, + tb_inst_get_symbol_address(p->func, src.symbol), + alignment, is_volatile); + return; + } + case cgValue_Addr: + case cgValue_Symbol: + GB_PANIC("should be handled above"); + break; + } +} + + + gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) { if (as->op.kind == Token_Eq) { auto lvals = array_make<cgAddr>(permanent_allocator(), 0, as->lhs.count); |