Browse Source

Planning for multi-valued expressions in the tilde backend

gingerBill 2 years ago
parent
commit
55733171c1
5 changed files with 45 additions and 5 deletions
  1. 13 0
      src/tilde_backend.cpp
  2. 9 0
      src/tilde_backend.hpp
  3. 4 0
      src/tilde_expr.cpp
  4. 4 5
      src/tilde_proc.cpp
  5. 15 0
      src/tilde_stmt.cpp

+ 13 - 0
src/tilde_backend.cpp

@@ -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;

+ 9 - 0
src/tilde_backend.hpp

@@ -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;

+ 4 - 0
src/tilde_expr.cpp

@@ -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
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;
 		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 = 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_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);

+ 15 - 0
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:
 		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);