From 0230b8807851de2b1e9975a1c292a0a4471936f9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 7 Aug 2023 15:11:15 +0100 Subject: [PATCH] Tilde: #soa pointers --- src/tilde_expr.cpp | 25 +++++++++++----- src/tilde_stmt.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index ece8e0816..dfb04774e 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -2796,6 +2796,16 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { return v; } +gb_internal cgValue cg_make_soa_pointer(cgProcedure *p, Type *type, cgValue const &addr, cgValue const &index) { + cgAddr v = cg_add_local(p, type, nullptr, true); + cgValue ptr = cg_emit_struct_ep(p, v.addr, 0); + cgValue idx = cg_emit_struct_ep(p, v.addr, 1); + cg_emit_store(p, ptr, addr); + cg_emit_store(p, idx, cg_emit_conv(p, index, t_int)); + + return cg_addr_load(p, v); +} + gb_internal cgValue cg_build_unary_and(cgProcedure *p, Ast *expr) { ast_node(ue, UnaryExpr, expr); auto tv = type_and_value_of_expr(expr); @@ -2835,16 +2845,15 @@ gb_internal cgValue cg_build_unary_and(cgProcedure *p, Ast *expr) { // return lb_addr_load(p, res); } else if (is_type_soa_pointer(tv.type)) { - GB_PANIC("TODO(bill): &soa[i]"); - // ast_node(ie, IndexExpr, ue_expr); - // lbValue addr = lb_build_addr_ptr(p, ie->expr); - // lbValue index = lb_build_expr(p, ie->index); + ast_node(ie, IndexExpr, ue_expr); + cgValue addr = cg_build_addr_ptr(p, ie->expr); + cgValue index = cg_build_expr(p, ie->index); - // if (!build_context.no_bounds_check) { - // // TODO(bill): soa bounds checking - // } + if (!build_context.no_bounds_check) { + // TODO(bill): soa bounds checking + } - // return lb_make_soa_pointer(p, tv.type, addr, index); + return cg_make_soa_pointer(p, tv.type, addr, index); } else if (ue_expr->kind == Ast_CompoundLit) { cgAddr addr = cg_build_addr_compound_lit(p, expr); return addr.addr; diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index e27275b04..5caf5d52e 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -254,6 +254,63 @@ gb_internal cgValue cg_addr_load(cgProcedure *p, cgAddr addr) { return v; } } + + case cgAddr_SoaVariable: + { + Type *t = type_deref(addr.addr.type); + t = base_type(t); + GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None); + Type *elem = t->Struct.soa_elem; + + cgValue len = {}; + if (t->Struct.soa_kind == StructSoa_Fixed) { + len = cg_const_int(p, t_int, t->Struct.soa_count); + } else { + cgValue v = cg_emit_load(p, addr.addr); + len = cg_builtin_len(p, v); + } + + cgAddr res = cg_add_local(p, elem, nullptr, true); + + // if (addr.soa.index_expr != nullptr && (!cg_is_const(addr.soa.index) || t->Struct.soa_kind != StructSoa_Fixed)) { + // cg_emit_bounds_check(p, ast_token(addr.soa.index_expr), addr.soa.index, len); + // } + + if (t->Struct.soa_kind == StructSoa_Fixed) { + for_array(i, t->Struct.fields) { + Entity *field = t->Struct.fields[i]; + Type *base_type = field->type; + GB_ASSERT(base_type->kind == Type_Array); + + cgValue dst = cg_emit_struct_ep(p, res.addr, cast(i32)i); + cgValue src_ptr = cg_emit_struct_ep(p, addr.addr, cast(i32)i); + src_ptr = cg_emit_array_ep(p, src_ptr, addr.soa.index); + cgValue src = cg_emit_load(p, src_ptr); + cg_emit_store(p, dst, src); + } + } else { + isize field_count = t->Struct.fields.count; + if (t->Struct.soa_kind == StructSoa_Slice) { + field_count -= 1; + } else if (t->Struct.soa_kind == StructSoa_Dynamic) { + field_count -= 3; + } + for (isize i = 0; i < field_count; i++) { + Entity *field = t->Struct.fields[i]; + Type *base_type = field->type; + GB_ASSERT(base_type->kind == Type_Pointer); + + cgValue dst = cg_emit_struct_ep(p, res.addr, cast(i32)i); + cgValue src_ptr = cg_emit_struct_ep(p, addr.addr, cast(i32)i); + cgValue src = cg_emit_load(p, src_ptr); + src = cg_emit_ptr_offset(p, src, addr.soa.index); + src = cg_emit_load(p, src); + cg_emit_store(p, dst, src); + } + } + + return cg_addr_load(p, res); + } } GB_PANIC("TODO(bill): cg_addr_load %p", addr.addr.node); return {}; @@ -562,18 +619,24 @@ gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) { return cg_emit_array_epi(p, s, index); case Type_SoaPointer: switch (index) { - case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break; - case 1: result_type = t_int; break; + case 0: + result_type = alloc_type_pointer(t->SoaPointer.elem); + offset = 0; + break; + case 1: + result_type = t_int; + offset = int_size; + break; } break; default: error_case:; - GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(s.type), index); + GB_PANIC("TODO(bill): struct_gep type: %s, %lld", type_to_string(s.type), cast(long long)index); break; } - GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index); - GB_ASSERT(offset >= 0); + GB_ASSERT_MSG(result_type != nullptr, "%s %lld", type_to_string(t), cast(long long)index); + GB_ASSERT_MSG(offset >= 0, "%s %lld", type_to_string(t), cast(long long)offset); GB_ASSERT(s.kind == cgValue_Value); return cg_value(