aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tilde_backend.cpp13
-rw-r--r--src/tilde_backend.hpp9
-rw-r--r--src/tilde_expr.cpp4
-rw-r--r--src/tilde_proc.cpp9
-rw-r--r--src/tilde_stmt.cpp15
5 files changed, 45 insertions, 5 deletions
diff --git a/src/tilde_backend.cpp b/src/tilde_backend.cpp
index 00e665b62..97f2dcccd 100644
--- a/src/tilde_backend.cpp
+++ b/src/tilde_backend.cpp
@@ -118,7 +118,20 @@ gb_internal cgValue cg_lvalue_addr(TB_Node *node, Type *type) {
return v;
}
+gb_internal cgValue cg_value_multi(cgValueMultiNodes *multi_nodes, Type *type) {
+ GB_ASSERT(type->kind == Type_Tuple);
+ GB_ASSERT(multi_nodes != nullptr);
+ GB_ASSERT(type->Tuple.variables.count > 1);
+ GB_ASSERT(multi_nodes->nodes.count == type->Tuple.variables.count);
+ cgValue v = {};
+ v.kind = cgValue_Multi;
+ v.type = type;
+ v.multi_nodes = multi_nodes;
+ return v;
+}
+
gb_internal cgAddr cg_addr(cgValue const &value) {
+ GB_ASSERT(value.kind != cgValue_Multi);
cgAddr addr = {};
addr.kind = cgAddr_Default;
addr.addr = value;
diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp
index 9e88cb4c7..54d84302d 100644
--- a/src/tilde_backend.hpp
+++ b/src/tilde_backend.hpp
@@ -34,6 +34,11 @@ enum cgValueKind : u32 {
cgValue_Value,
cgValue_Addr,
cgValue_Symbol,
+ cgValue_Multi,
+};
+
+struct cgValueMultiNodes {
+ Slice<TB_Node *> nodes;
};
struct cgValue {
@@ -42,6 +47,7 @@ struct cgValue {
union {
TB_Symbol *symbol;
TB_Node * node;
+ cgValueMultiNodes *multi_nodes;
};
};
@@ -132,6 +138,9 @@ struct cgProcedure {
TB_FunctionPrototype *proto;
TB_Symbol *symbol;
+ // includes parameters, pointers to return values, and context ptr
+ Slice<TB_Node *> param_nodes;
+
Entity * entity;
cgModule *module;
String name;
diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp
index 4e43089b2..473baf763 100644
--- a/src/tilde_expr.cpp
+++ b/src/tilde_expr.cpp
@@ -1,4 +1,5 @@
gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value) {
+ GB_ASSERT(value.kind != cgValue_Multi);
if (value.kind == cgValue_Symbol) {
GB_ASSERT(is_type_internally_pointer_like(value.type));
value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), value.type);
@@ -152,6 +153,9 @@ gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type)
case cgValue_Symbol:
GB_PANIC("should be handled above");
break;
+ case cgValue_Multi:
+ GB_PANIC("cannot transmute multiple values at once");
+ break;
}
return value;
diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp
index 078c2ef9c..d08f611fc 100644
--- a/src/tilde_proc.cpp
+++ b/src/tilde_proc.cpp
@@ -333,7 +333,7 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
size_t out_param_count = 0;
p->debug_type = cg_debug_type_for_proc(m, p->type);
TB_Node **params = tb_function_set_prototype_from_dbg(p->func, p->debug_type, arena, &out_param_count);
- gb_unused(params);
+ p->param_nodes = {params, cast(isize)out_param_count};
p->proto = tb_function_get_prototype(p->func);
p->symbol = cast(TB_Symbol *)p->func;
@@ -387,7 +387,7 @@ gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &li
size_t out_param_count = 0;
p->debug_type = cg_debug_type_for_proc(m, p->type);
TB_Node **params = tb_function_set_prototype_from_dbg(p->func, p->debug_type, arena, &out_param_count);
- gb_unused(params);
+ p->param_nodes = {params, cast(isize)out_param_count};
p->proto = tb_function_get_prototype(p->func);
@@ -420,12 +420,11 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
continue;
}
- if (param_index >= p->proto->param_count) {
+ if (param_index >= p->param_nodes.count) {
break;
}
- // TB_Node *ptr = tb_inst_param_addr(p->func, param_index);
- TB_Node *param = tb_inst_param(p->func, param_index++);
+ TB_Node *param = p->param_nodes[param_index++];
TB_Node *ptr = tb_inst_local(p->func, cast(TB_CharUnits)type_size_of(e->type), cast(TB_CharUnits)type_align_of(e->type));
TB_DataType dt = cg_data_type(e->type);
tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false);
diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp
index afc915115..6680277ed 100644
--- a/src/tilde_stmt.cpp
+++ b/src/tilde_stmt.cpp
@@ -10,6 +10,9 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol
case cgValue_Addr:
GB_PANIC("NOT POSSIBLE - Cannot load an lvalue to begin with");
break;
+ case cgValue_Multi:
+ GB_PANIC("NOT POSSIBLE - Cannot load multiple values at once");
+ break;
case cgValue_Symbol:
return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type);
}
@@ -27,6 +30,9 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol
case cgValue_Addr:
the_ptr = tb_inst_load(p->func, TB_TYPE_PTR, ptr.node, alignment, is_volatile);
break;
+ case cgValue_Multi:
+ GB_PANIC("NOT POSSIBLE - Cannot load multiple values at once");
+ break;
case cgValue_Symbol:
the_ptr = tb_inst_get_symbol_address(p->func, ptr.symbol);
break;
@@ -35,6 +41,8 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol
}
gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src, bool is_volatile) {
+ GB_ASSERT_MSG(dst.kind != cgValue_Multi, "cannot store to multiple values at once");
+
if (dst.kind == cgValue_Addr) {
dst = cg_emit_load(p, dst, is_volatile);
} else if (dst.kind == cgValue_Symbol) {
@@ -130,6 +138,9 @@ gb_internal cgValue cg_address_from_load(cgProcedure *p, cgValue value) {
case cgValue_Symbol:
GB_PANIC("Symbol is an invalid use case for cg_address_from_load");
return {};
+ case cgValue_Multi:
+ GB_PANIC("Multi is an invalid use case for cg_address_from_load");
+ break;
}
GB_PANIC("Invalid cgValue for cg_address_from_load");
return {};
@@ -143,6 +154,8 @@ gb_internal bool cg_addr_is_empty(cgAddr const &addr) {
return addr.addr.node == nullptr;
case cgValue_Symbol:
return addr.addr.symbol == nullptr;
+ case cgValue_Multi:
+ return addr.addr.multi_nodes == nullptr;
}
return true;
}
@@ -670,6 +683,8 @@ gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgVal
break;
case cgValue_Addr:
return cg_value(value.node, alloc_type_pointer(value.type));
+ case cgValue_Multi:
+ GB_PANIC("cgValue_Multi not allowed");
}
cgAddr res = cg_add_local(p, value.type, nullptr, false);