Browse Source

Mock out more of the addr related stuff

gingerBill 2 years ago
parent
commit
b17ebeb6f6
5 changed files with 323 additions and 135 deletions
  1. 42 39
      src/tilde_backend.cpp
  2. 4 2
      src/tilde_backend.hpp
  3. 40 0
      src/tilde_const.cpp
  4. 6 0
      src/tilde_expr.cpp
  5. 231 94
      src/tilde_stmt.cpp

+ 42 - 39
src/tilde_backend.cpp

@@ -4,58 +4,61 @@
 gb_internal TB_DataType cg_data_type(Type *t) {
 	GB_ASSERT(t != nullptr);
 	t = core_type(t);
+	i64 sz = type_size_of(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_bool:
+		case Basic_b8:
+		case Basic_b16:
+		case Basic_b32:
+		case Basic_b64:
+
+		case Basic_i8:
+		case Basic_u8:
+		case Basic_i16:
+		case Basic_u16:
+		case Basic_i32:
+		case Basic_u32:
+		case Basic_i64:
+		case Basic_u64:
+		case Basic_i128:
+		case Basic_u128:
+
+		case Basic_rune:
+
+		case Basic_int:
+		case Basic_uint:
+		case Basic_uintptr:
+		case Basic_typeid:
+			return TB_TYPE_INTN(cast(u16)(8*sz));
 
 		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_i16le:
+		case Basic_u16le:
+		case Basic_i32le:
+		case Basic_u32le:
+		case Basic_i64le:
+		case Basic_u64le:
+		case Basic_i128le:
+		case Basic_u128le:
+		case Basic_i16be:
+		case Basic_u16be:
+		case Basic_i32be:
+		case Basic_u32be:
+		case Basic_i64be:
+		case Basic_u64be:
+		case Basic_i128be:
+		case Basic_u128be:
+			return TB_TYPE_INTN(cast(u16)(8*sz));
 
 		case Basic_f16le: return TB_TYPE_I16;
 		case Basic_f32le: return TB_TYPE_F32;

+ 4 - 2
src/tilde_backend.hpp

@@ -7,8 +7,9 @@
 
 #include "tilde/tb.h"
 
-#define TB_TYPE_I128  TB_DataType{ { TB_INT, 0, 128 } }
-
+#define TB_TYPE_I128   TB_DataType{ { TB_INT, 0, 128 } }
+#define TB_TYPE_INT    TB_TYPE_INTN(cast(u16)build_context.int_size)
+#define TB_TYPE_INTPTR TB_TYPE_INTN(cast(u16)build_context.ptr_size)
 
 #if defined(GB_SYSTEM_WINDOWS)
 	#pragma warning(pop)
@@ -162,6 +163,7 @@ struct cgModule {
 	PtrMap<uintptr, TB_FileID> file_id_map; // Key: AstFile.id (i32 cast to uintptr)
 
 	std::atomic<u32> nested_type_name_guid;
+	std::atomic<u32> const_nil_guid;
 };
 
 #ifndef ABI_PKG_NAME_SEPARATOR

+ 40 - 0
src/tilde_const.cpp

@@ -1,5 +1,45 @@
+gb_internal cgValue cg_const_nil(cgProcedure *p, Type *type) {
+	Type *original_type = type;
+	type = core_type(type);
+	i64 size = type_size_of(type);
+	i64 align = type_align_of(type);
+	TB_DataType dt = cg_data_type(type);
+	if (TB_IS_VOID_TYPE(dt)) {
+		TB_Module *m = p->module->mod;
+		char name[32] = {};
+		gb_snprintf(name, 31, "cnil$%u", 1+p->module->const_nil_guid.fetch_add(1));
+		TB_Global *global = tb_global_create(m, name, nullptr, TB_LINKAGE_PRIVATE);
+		tb_global_set_storage(m, tb_module_get_rdata(m), global, size, align, 0);
+
+		TB_Symbol *symbol = cast(TB_Symbol *)global;
+		TB_Node *node = tb_inst_get_symbol_address(p->func, symbol);
+		return cg_lvalue_addr(node, type);
+	}
+
+	if (is_type_internally_pointer_like(type)) {
+		return cg_value(tb_inst_ptr(p->func, 0), type);
+	} else if (is_type_integer(type) || is_type_boolean(type) || is_type_bit_set(type)) {
+		return cg_value(tb_inst_uint(p->func, dt, 0), type);
+	} else if (is_type_float(type)) {
+		switch (size) {
+		case 2:
+			return cg_value(tb_inst_uint(p->func, dt, 0), type);
+		case 4:
+			return cg_value(tb_inst_float32(p->func, 0), type);
+		case 8:
+			return cg_value(tb_inst_float64(p->func, 0), type);
+		}
+	}
+	GB_PANIC("TODO(bill): cg_const_nil %s", type_to_string(original_type));
+	return {};
+}
+
 gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const &value) {
 	TB_Node *node = nullptr;
 
+	if (value.kind == ExactValue_Invalid) {
+		return cg_const_nil(p, type);
+	}
+
 	return cg_value(node, type);
 }

+ 6 - 0
src/tilde_expr.cpp

@@ -1,3 +1,9 @@
+gb_internal cgValue cg_emit_conv(cgProcedure *p, cgValue value, Type *type) {
+	// TODO(bill): cg_emit_conv
+	return value;
+}
+
+
 gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr);
 gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) {
 	u16 prev_state_flags = p->state_flags;

+ 231 - 94
src/tilde_stmt.cpp

@@ -1,3 +1,223 @@
+
+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);
+
+	TB_CharUnits alignment = 1; // for the time being
+
+	if (TB_IS_VOID_TYPE(dt)) {
+		TB_Node *dst_ptr = nullptr;
+		TB_Node *src_ptr = nullptr;
+
+		switch (dst.kind) {
+		case cgValue_Value:
+			dst_ptr	= dst.node;
+			break;
+		case cgValue_Addr:
+			GB_PANIC("DST cgValue_Addr should be handled above");
+			break;
+		case cgValue_Symbol:
+			dst_ptr = tb_inst_get_symbol_address(p->func, dst.symbol);
+			break;
+		}
+
+		switch (src.kind) {
+		case cgValue_Value:
+			GB_PANIC("SRC cgValue_Value should be handled above");
+			break;
+		case cgValue_Symbol:
+			GB_PANIC("SRC cgValue_Symbol should be handled above");
+			break;
+		case cgValue_Addr:
+			src_ptr = src.node;
+			break;
+		}
+
+		// IMPORTANT TODO(bill): needs to be memmove
+		i64 sz = type_size_of(dst_type);
+		TB_Node *count = tb_inst_uint(p->func, TB_TYPE_INT, cast(u64)sz);
+		tb_inst_memcpy(p->func, dst_ptr, src_ptr, count, alignment, is_volatile);
+		return;
+	}
+
+	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:
+		GB_PANIC("cgValue_Addr should be handled above");
+		break;
+	case cgValue_Symbol:
+		GB_PANIC(" cgValue_Symbol should be handled above");
+		break;
+	}
+}
+
+
+gb_internal cgValue cg_address_from_load(cgProcedure *p, cgValue value) {
+	switch (value.kind) {
+	case cgValue_Value:
+		{
+			TB_Node *load_inst = value.node;
+			GB_ASSERT_MSG(load_inst->type == TB_LOAD, "expected a load instruction");
+			TB_Node *ptr = load_inst->inputs[1];
+			return cg_value(ptr, alloc_type_pointer(value.type));
+		}
+	case cgValue_Addr:
+		return cg_value(value.node, alloc_type_pointer(value.type));
+	case cgValue_Symbol:
+		GB_PANIC("Symbol is an invalid use case for cg_address_from_load");
+		return {};
+	}
+}
+
+gb_internal bool cg_addr_is_empty(cgAddr const &addr) {
+	switch (addr.kind) {
+	case cgValue_Value:
+	case cgValue_Addr:
+		return addr.addr.node == nullptr;
+	case cgValue_Symbol:
+		return addr.addr.symbol == nullptr;
+	}
+	return true;
+}
+
+gb_internal Type *cg_addr_type(cgAddr const &addr) {
+	if (cg_addr_is_empty(addr)) {
+		return nullptr;
+	}
+	switch (addr.kind) {
+	case cgAddr_Map:
+		{
+			Type *t = base_type(addr.map.type);
+			GB_ASSERT(is_type_map(t));
+			return t->Map.value;
+		}
+	case cgAddr_Swizzle:
+		return addr.swizzle.type;
+	case cgAddr_SwizzleLarge:
+		return addr.swizzle_large.type;
+	case cgAddr_Context:
+		if (addr.ctx.sel.index.count > 0) {
+			Type *t = t_context;
+			for_array(i, addr.ctx.sel.index) {
+				GB_ASSERT(is_type_struct(t));
+				t = base_type(t)->Struct.fields[addr.ctx.sel.index[i]]->type;
+			}
+			return t;
+		}
+		break;
+	}
+	return type_deref(addr.addr.type);
+}
+
+gb_internal cgValue cg_addr_load(cgProcedure *p, cgAddr addr) {
+	GB_PANIC("TODO(bill): cg_addr_load");
+	return {};
+}
+
+
+gb_internal void cg_addr_store(cgProcedure *p, cgAddr addr, cgValue value) {
+	if (cg_addr_is_empty(addr)) {
+		return;
+	}
+	GB_ASSERT(value.type != nullptr);
+	if (is_type_untyped_uninit(value.type)) {
+		Type *t = cg_addr_type(addr);
+		value = cg_value(tb_inst_poison(p->func), t);
+		// TODO(bill): IS THIS EVEN A GOOD IDEA?
+	} else if (is_type_untyped_nil(value.type)) {
+		Type *t = cg_addr_type(addr);
+		value = cg_const_nil(p, t);
+	}
+
+	if (addr.kind == cgAddr_RelativePointer && addr.relative.deref) {
+		addr = cg_addr(cg_address_from_load(p, cg_addr_load(p, addr)));
+	}
+
+	if (addr.kind == cgAddr_RelativePointer) {
+		GB_PANIC("TODO(bill): cgAddr_RelativePointer");
+	} else if (addr.kind == cgAddr_RelativeSlice) {
+		GB_PANIC("TODO(bill): cgAddr_RelativeSlice");
+	} else if (addr.kind == cgAddr_Map) {
+		GB_PANIC("TODO(bill): cgAddr_Map");
+	} else if (addr.kind == cgAddr_Context) {
+		GB_PANIC("TODO(bill): cgAddr_Context");
+	} else if (addr.kind == cgAddr_SoaVariable) {
+		GB_PANIC("TODO(bill): cgAddr_SoaVariable");
+	} else if (addr.kind == cgAddr_Swizzle) {
+		GB_ASSERT(addr.swizzle.count <= 4);
+		GB_PANIC("TODO(bill): cgAddr_Swizzle");
+	} else if (addr.kind == cgAddr_SwizzleLarge) {
+		GB_PANIC("TODO(bill): cgAddr_SwizzleLarge");
+	}
+
+	value = cg_emit_conv(p, value, cg_addr_type(addr));
+	cg_emit_store(p, addr.addr, value);
+}
+
+
+
+
 gb_internal cgBranchBlocks cg_lookup_branch_blocks(cgProcedure *p, Ast *ident) {
 	GB_ASSERT(ident->kind == Ast_Ident);
 	Entity *e = entity_of_node(ident);
@@ -91,95 +311,12 @@ gb_internal void cg_emit_defer_stmts(cgProcedure *p, cgDeferExitKind kind, TB_No
 	// TODO(bill): cg_emit_defer_stmts
 }
 
-gb_internal void cg_build_assignment(cgProcedure *p, Array<cgAddr> const &lhs, Slice<Ast *> const &rhs) {
-
-}
-
-
-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");
+gb_internal void cg_build_assignment(cgProcedure *p, Array<cgAddr> const &lvals, Slice<Ast *> const &values) {
+	if (values.count == 0) {
 		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);
@@ -213,19 +350,19 @@ gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) {
 		cgValue new_value = lb_emit_logical_binary_expr(p, op, as->lhs[0], as->rhs[0], type);
 
 		cgAddr lhs = lb_build_addr(p, as->lhs[0]);
-		lb_addr_store(p, lhs, new_value);
+		cg_addr_store(p, lhs, new_value);
 	} else {
 		cgAddr lhs = lb_build_addr(p, as->lhs[0]);
-		lbValue value = lb_build_expr(p, as->rhs[0]);
+		cgValue value = lb_build_expr(p, as->rhs[0]);
 		Type *lhs_type = lb_addr_type(lhs);
 
 		// NOTE(bill): Allow for the weird edge case of:
 		// array *= matrix
 		if (op == Token_Mul && is_type_matrix(value.type) && is_type_array(lhs_type)) {
-			lbValue old_value = lb_addr_load(p, lhs);
+			cgValue old_value = lb_addr_load(p, lhs);
 			Type *type = old_value.type;
-			lbValue new_value = lb_emit_vector_mul_matrix(p, old_value, value, type);
-			lb_addr_store(p, lhs, new_value);
+			cgValue new_value = lb_emit_vector_mul_matrix(p, old_value, value, type);
+			cg_addr_store(p, lhs, new_value);
 			return;
 		}
 
@@ -233,12 +370,12 @@ gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) {
 			lb_build_assign_stmt_array(p, op, lhs, value);
 			return;
 		} else {
-			lbValue old_value = lb_addr_load(p, lhs);
+			cgValue old_value = lb_addr_load(p, lhs);
 			Type *type = old_value.type;
 
-			lbValue change = lb_emit_conv(p, value, type);
-			lbValue new_value = lb_emit_arith(p, op, old_value, change, type);
-			lb_addr_store(p, lhs, new_value);
+			cgValue change = lb_emit_conv(p, value, type);
+			cgValue new_value = lb_emit_arith(p, op, old_value, change, type);
+			cg_addr_store(p, lhs, new_value);
 		}
 	}
 */