mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
Planning for multi-valued expressions in the tilde backend
This commit is contained in:
@@ -118,7 +118,20 @@ gb_internal cgValue cg_lvalue_addr(TB_Node *node, Type *type) {
|
|||||||
return v;
|
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_internal cgAddr cg_addr(cgValue const &value) {
|
||||||
|
GB_ASSERT(value.kind != cgValue_Multi);
|
||||||
cgAddr addr = {};
|
cgAddr addr = {};
|
||||||
addr.kind = cgAddr_Default;
|
addr.kind = cgAddr_Default;
|
||||||
addr.addr = value;
|
addr.addr = value;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ enum cgValueKind : u32 {
|
|||||||
cgValue_Value,
|
cgValue_Value,
|
||||||
cgValue_Addr,
|
cgValue_Addr,
|
||||||
cgValue_Symbol,
|
cgValue_Symbol,
|
||||||
|
cgValue_Multi,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cgValueMultiNodes {
|
||||||
|
Slice<TB_Node *> nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cgValue {
|
struct cgValue {
|
||||||
@@ -42,6 +47,7 @@ struct cgValue {
|
|||||||
union {
|
union {
|
||||||
TB_Symbol *symbol;
|
TB_Symbol *symbol;
|
||||||
TB_Node * node;
|
TB_Node * node;
|
||||||
|
cgValueMultiNodes *multi_nodes;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,6 +138,9 @@ struct cgProcedure {
|
|||||||
TB_FunctionPrototype *proto;
|
TB_FunctionPrototype *proto;
|
||||||
TB_Symbol *symbol;
|
TB_Symbol *symbol;
|
||||||
|
|
||||||
|
// includes parameters, pointers to return values, and context ptr
|
||||||
|
Slice<TB_Node *> param_nodes;
|
||||||
|
|
||||||
Entity * entity;
|
Entity * entity;
|
||||||
cgModule *module;
|
cgModule *module;
|
||||||
String name;
|
String name;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value) {
|
gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value) {
|
||||||
|
GB_ASSERT(value.kind != cgValue_Multi);
|
||||||
if (value.kind == cgValue_Symbol) {
|
if (value.kind == cgValue_Symbol) {
|
||||||
GB_ASSERT(is_type_internally_pointer_like(value.type));
|
GB_ASSERT(is_type_internally_pointer_like(value.type));
|
||||||
value = cg_value(tb_inst_get_symbol_address(p->func, value.symbol), 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:
|
case cgValue_Symbol:
|
||||||
GB_PANIC("should be handled above");
|
GB_PANIC("should be handled above");
|
||||||
break;
|
break;
|
||||||
|
case cgValue_Multi:
|
||||||
|
GB_PANIC("cannot transmute multiple values at once");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -333,7 +333,7 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
|
|||||||
size_t out_param_count = 0;
|
size_t out_param_count = 0;
|
||||||
p->debug_type = cg_debug_type_for_proc(m, p->type);
|
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);
|
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->proto = tb_function_get_prototype(p->func);
|
||||||
|
|
||||||
p->symbol = cast(TB_Symbol *)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;
|
size_t out_param_count = 0;
|
||||||
p->debug_type = cg_debug_type_for_proc(m, p->type);
|
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);
|
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->proto = tb_function_get_prototype(p->func);
|
||||||
|
|
||||||
|
|
||||||
@@ -420,12 +420,11 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param_index >= p->proto->param_count) {
|
if (param_index >= p->param_nodes.count) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TB_Node *ptr = tb_inst_param_addr(p->func, param_index);
|
TB_Node *param = p->param_nodes[param_index++];
|
||||||
TB_Node *param = tb_inst_param(p->func, 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_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_DataType dt = cg_data_type(e->type);
|
||||||
tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false);
|
tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false);
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol
|
|||||||
case cgValue_Addr:
|
case cgValue_Addr:
|
||||||
GB_PANIC("NOT POSSIBLE - Cannot load an lvalue to begin with");
|
GB_PANIC("NOT POSSIBLE - Cannot load an lvalue to begin with");
|
||||||
break;
|
break;
|
||||||
|
case cgValue_Multi:
|
||||||
|
GB_PANIC("NOT POSSIBLE - Cannot load multiple values at once");
|
||||||
|
break;
|
||||||
case cgValue_Symbol:
|
case cgValue_Symbol:
|
||||||
return cg_lvalue_addr(tb_inst_get_symbol_address(p->func, ptr.symbol), type);
|
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:
|
case cgValue_Addr:
|
||||||
the_ptr = tb_inst_load(p->func, TB_TYPE_PTR, ptr.node, alignment, is_volatile);
|
the_ptr = tb_inst_load(p->func, TB_TYPE_PTR, ptr.node, alignment, is_volatile);
|
||||||
break;
|
break;
|
||||||
|
case cgValue_Multi:
|
||||||
|
GB_PANIC("NOT POSSIBLE - Cannot load multiple values at once");
|
||||||
|
break;
|
||||||
case cgValue_Symbol:
|
case cgValue_Symbol:
|
||||||
the_ptr = tb_inst_get_symbol_address(p->func, ptr.symbol);
|
the_ptr = tb_inst_get_symbol_address(p->func, ptr.symbol);
|
||||||
break;
|
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_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) {
|
if (dst.kind == cgValue_Addr) {
|
||||||
dst = cg_emit_load(p, dst, is_volatile);
|
dst = cg_emit_load(p, dst, is_volatile);
|
||||||
} else if (dst.kind == cgValue_Symbol) {
|
} else if (dst.kind == cgValue_Symbol) {
|
||||||
@@ -130,6 +138,9 @@ gb_internal cgValue cg_address_from_load(cgProcedure *p, cgValue value) {
|
|||||||
case cgValue_Symbol:
|
case cgValue_Symbol:
|
||||||
GB_PANIC("Symbol is an invalid use case for cg_address_from_load");
|
GB_PANIC("Symbol is an invalid use case for cg_address_from_load");
|
||||||
return {};
|
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");
|
GB_PANIC("Invalid cgValue for cg_address_from_load");
|
||||||
return {};
|
return {};
|
||||||
@@ -143,6 +154,8 @@ gb_internal bool cg_addr_is_empty(cgAddr const &addr) {
|
|||||||
return addr.addr.node == nullptr;
|
return addr.addr.node == nullptr;
|
||||||
case cgValue_Symbol:
|
case cgValue_Symbol:
|
||||||
return addr.addr.symbol == nullptr;
|
return addr.addr.symbol == nullptr;
|
||||||
|
case cgValue_Multi:
|
||||||
|
return addr.addr.multi_nodes == nullptr;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -670,6 +683,8 @@ gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgVal
|
|||||||
break;
|
break;
|
||||||
case cgValue_Addr:
|
case cgValue_Addr:
|
||||||
return cg_value(value.node, alloc_type_pointer(value.type));
|
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);
|
cgAddr res = cg_add_local(p, value.type, nullptr, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user