Browse Source

Update Tilde; mock out `cg_build_return_stmt`

128-bit types are broken
gingerBill 2 years ago
parent
commit
bd73834e19
7 changed files with 125 additions and 77 deletions
  1. 20 6
      src/tilde/tb.h
  2. BIN
      src/tilde/tb.lib
  3. 2 2
      src/tilde_backend.cpp
  4. 2 1
      src/tilde_backend.hpp
  5. 1 1
      src/tilde_const.cpp
  6. 73 66
      src/tilde_proc.cpp
  7. 27 1
      src/tilde_stmt.cpp

+ 20 - 6
src/tilde/tb.h

@@ -195,8 +195,6 @@ typedef union TB_DataType {
 typedef enum TB_NodeTypeEnum {
 typedef enum TB_NodeTypeEnum {
     TB_NULL = 0,
     TB_NULL = 0,
 
 
-    TB_RETURN, // fn(r: region, x: data)
-
     // only one per function
     // only one per function
     TB_START, // fn()
     TB_START, // fn()
 
 
@@ -823,7 +821,16 @@ TB_API TB_DebugType* tb_debug_create_array(TB_Module* m, TB_DebugType* base, siz
 TB_API TB_DebugType* tb_debug_create_struct(TB_Module* m, ptrdiff_t len, const char* tag);
 TB_API TB_DebugType* tb_debug_create_struct(TB_Module* m, ptrdiff_t len, const char* tag);
 TB_API TB_DebugType* tb_debug_create_union(TB_Module* m, ptrdiff_t len, const char* tag);
 TB_API TB_DebugType* tb_debug_create_union(TB_Module* m, ptrdiff_t len, const char* tag);
 TB_API TB_DebugType* tb_debug_create_field(TB_Module* m, TB_DebugType* type, ptrdiff_t len, const char* name, TB_CharUnits offset);
 TB_API TB_DebugType* tb_debug_create_field(TB_Module* m, TB_DebugType* type, ptrdiff_t len, const char* name, TB_CharUnits offset);
-TB_API void tb_debug_complete_record(TB_DebugType* type, TB_DebugType** members, size_t count, TB_CharUnits size, TB_CharUnits align);
+
+// returns the array you need to fill with fields
+TB_API TB_DebugType** tb_debug_record_begin(TB_DebugType* type, size_t count);
+TB_API void tb_debug_record_end(TB_DebugType* type, TB_CharUnits size, TB_CharUnits align);
+
+TB_API TB_DebugType* tb_debug_create_func(TB_Module* m, TB_CallingConv cc, size_t param_count, size_t return_count, bool has_varargs);
+
+// you'll need to fill these if you make a function
+TB_API TB_DebugType** tb_debug_func_params(TB_DebugType* type);
+TB_API TB_DebugType** tb_debug_func_returns(TB_DebugType* type);
 
 
 ////////////////////////////////
 ////////////////////////////////
 // IR access
 // IR access
@@ -850,6 +857,8 @@ TB_API TB_Global* tb_symbol_as_global(TB_Symbol* s);
 ////////////////////////////////
 ////////////////////////////////
 // Function IR Generation
 // Function IR Generation
 ////////////////////////////////
 ////////////////////////////////
+TB_API void tb_get_data_type_size(TB_Module* mod, TB_DataType dt, size_t* size, size_t* align);
+
 // the user_data is expected to be a valid FILE*
 // the user_data is expected to be a valid FILE*
 TB_API void tb_default_print_callback(void* user_data, const char* fmt, ...);
 TB_API void tb_default_print_callback(void* user_data, const char* fmt, ...);
 
 
@@ -869,6 +878,12 @@ TB_API void tb_symbol_set_name(TB_Symbol* s, ptrdiff_t len, const char* name);
 TB_API void tb_symbol_bind_ptr(TB_Symbol* s, void* ptr);
 TB_API void tb_symbol_bind_ptr(TB_Symbol* s, void* ptr);
 TB_API const char* tb_symbol_get_name(TB_Symbol* s);
 TB_API const char* tb_symbol_get_name(TB_Symbol* s);
 
 
+// same as tb_function_set_prototype except it will handle lowering from types like the TB_DebugType
+// into the correct ABI and exposing sane looking nodes to the parameters.
+//
+// returns the parameters
+TB_API TB_Node** tb_function_set_prototype_from_dbg(TB_Function* f, TB_DebugType* dbg, TB_Arena* arena, size_t* out_param_count);
+
 // if arena is NULL, defaults to module arena which is freed on tb_free_thread_resources
 // if arena is NULL, defaults to module arena which is freed on tb_free_thread_resources
 TB_API void tb_function_set_prototype(TB_Function* f, TB_FunctionPrototype* p, TB_Arena* arena);
 TB_API void tb_function_set_prototype(TB_Function* f, TB_FunctionPrototype* p, TB_Arena* arena);
 TB_API TB_FunctionPrototype* tb_function_get_prototype(TB_Function* f);
 TB_API TB_FunctionPrototype* tb_function_get_prototype(TB_Function* f);
@@ -890,7 +905,6 @@ TB_API void tb_inst_keep_alive(TB_Function* f, TB_Node* src);
 TB_API TB_Node* tb_inst_poison(TB_Function* f);
 TB_API TB_Node* tb_inst_poison(TB_Function* f);
 
 
 TB_API TB_Node* tb_inst_param(TB_Function* f, int param_id);
 TB_API TB_Node* tb_inst_param(TB_Function* f, int param_id);
-TB_API TB_Node* tb_inst_param_addr(TB_Function* f, int param_id);
 
 
 TB_API TB_Node* tb_inst_fpxt(TB_Function* f, TB_Node* src, TB_DataType dt);
 TB_API TB_Node* tb_inst_fpxt(TB_Function* f, TB_Node* src, TB_DataType dt);
 TB_API TB_Node* tb_inst_sxt(TB_Function* f, TB_Node* src, TB_DataType dt);
 TB_API TB_Node* tb_inst_sxt(TB_Function* f, TB_Node* src, TB_DataType dt);
@@ -902,7 +916,7 @@ TB_API TB_Node* tb_inst_int2float(TB_Function* f, TB_Node* src, TB_DataType dt,
 TB_API TB_Node* tb_inst_float2int(TB_Function* f, TB_Node* src, TB_DataType dt, bool is_signed);
 TB_API TB_Node* tb_inst_float2int(TB_Function* f, TB_Node* src, TB_DataType dt, bool is_signed);
 TB_API TB_Node* tb_inst_bitcast(TB_Function* f, TB_Node* src, TB_DataType dt);
 TB_API TB_Node* tb_inst_bitcast(TB_Function* f, TB_Node* src, TB_DataType dt);
 
 
-TB_API TB_Node* tb_inst_local(TB_Function* f, uint32_t size, TB_CharUnits align);
+TB_API TB_Node* tb_inst_local(TB_Function* f, TB_CharUnits size, TB_CharUnits align);
 TB_API TB_Node* tb_inst_load(TB_Function* f, TB_DataType dt, TB_Node* addr, TB_CharUnits align, bool is_volatile);
 TB_API TB_Node* tb_inst_load(TB_Function* f, TB_DataType dt, TB_Node* addr, TB_CharUnits align, bool is_volatile);
 TB_API void tb_inst_store(TB_Function* f, TB_DataType dt, TB_Node* addr, TB_Node* val, TB_CharUnits align, bool is_volatile);
 TB_API void tb_inst_store(TB_Function* f, TB_DataType dt, TB_Node* addr, TB_Node* val, TB_CharUnits align, bool is_volatile);
 
 
@@ -918,7 +932,7 @@ TB_API TB_Node* tb_inst_string(TB_Function* f, size_t len, const char* str);
 TB_API void tb_inst_memset(TB_Function* f, TB_Node* dst, TB_Node* val, TB_Node* count, TB_CharUnits align, bool is_volatile);
 TB_API void tb_inst_memset(TB_Function* f, TB_Node* dst, TB_Node* val, TB_Node* count, TB_CharUnits align, bool is_volatile);
 
 
 // zero 'count' bytes on 'dst'
 // zero 'count' bytes on 'dst'
-TB_API void tb_inst_memzero(TB_Function* f, TB_Node* dst, TB_Node* val, TB_Node* count, TB_CharUnits align, bool is_volatile);
+TB_API void tb_inst_memzero(TB_Function* f, TB_Node* dst, TB_Node* count, TB_CharUnits align, bool is_volatile);
 
 
 // performs a copy of 'count' elements from one memory location to another
 // performs a copy of 'count' elements from one memory location to another
 // both locations cannot overlap.
 // both locations cannot overlap.

BIN
src/tilde/tb.lib


+ 2 - 2
src/tilde_backend.cpp

@@ -31,7 +31,7 @@ gb_internal TB_DataType cg_data_type(Type *t) {
 		case Basic_uint:
 		case Basic_uint:
 		case Basic_uintptr:
 		case Basic_uintptr:
 		case Basic_typeid:
 		case Basic_typeid:
-			return TB_TYPE_INTN(cast(u16)(8*sz));
+			return TB_TYPE_INTN(cast(u16)gb_min(8*sz, 64));
 
 
 		case Basic_f16: return TB_TYPE_F16;
 		case Basic_f16: return TB_TYPE_F16;
 		case Basic_f32: return TB_TYPE_F32;
 		case Basic_f32: return TB_TYPE_F32;
@@ -58,7 +58,7 @@ gb_internal TB_DataType cg_data_type(Type *t) {
 		case Basic_u64be:
 		case Basic_u64be:
 		case Basic_i128be:
 		case Basic_i128be:
 		case Basic_u128be:
 		case Basic_u128be:
-			return TB_TYPE_INTN(cast(u16)(8*sz));
+			return TB_TYPE_INTN(cast(u16)gb_min(8*sz, 64));
 
 
 		case Basic_f16le: return TB_TYPE_F16;
 		case Basic_f16le: return TB_TYPE_F16;
 		case Basic_f32le: return TB_TYPE_F32;
 		case Basic_f32le: return TB_TYPE_F32;

+ 2 - 1
src/tilde_backend.hpp

@@ -8,7 +8,8 @@
 #include "tilde/tb.h"
 #include "tilde/tb.h"
 
 
 #define TB_TYPE_F16    TB_DataType{ { TB_INT, 0, 16 } }
 #define TB_TYPE_F16    TB_DataType{ { TB_INT, 0, 16 } }
-#define TB_TYPE_I128   TB_DataType{ { TB_INT, 0, 128 } }
+// #define TB_TYPE_I128   TB_DataType{ { TB_INT, 0, 128 } }
+#define TB_TYPE_I128   TB_TYPE_INTN(64)
 #define TB_TYPE_INT    TB_TYPE_INTN(cast(u16)(8*build_context.int_size))
 #define TB_TYPE_INT    TB_TYPE_INTN(cast(u16)(8*build_context.int_size))
 #define TB_TYPE_INTPTR TB_TYPE_INTN(cast(u16)(8*build_context.ptr_size))
 #define TB_TYPE_INTPTR TB_TYPE_INTN(cast(u16)(8*build_context.ptr_size))
 
 

+ 1 - 1
src/tilde_const.cpp

@@ -86,7 +86,7 @@ gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, Exac
 		return cg_value(tb_inst_uint(p->func, dt, value.value_bool), type);
 		return cg_value(tb_inst_uint(p->func, dt, value.value_bool), type);
 
 
 	case ExactValue_Integer:
 	case ExactValue_Integer:
-		GB_ASSERT(dt.raw != TB_TYPE_I128.raw);
+		// GB_ASSERT(dt.raw != TB_TYPE_I128.raw);
 		if (is_type_unsigned(type)) {
 		if (is_type_unsigned(type)) {
 			u64 i = exact_value_to_u64(value);
 			u64 i = exact_value_to_u64(value);
 			return cg_value(tb_inst_uint(p->func, dt, i), type);
 			return cg_value(tb_inst_uint(p->func, dt, i), type);

+ 73 - 66
src/tilde_proc.cpp

@@ -35,7 +35,7 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 			case Basic_int:
 			case Basic_int:
 			case Basic_uint:
 			case Basic_uint:
 			case Basic_uintptr:
 			case Basic_uintptr:
-				param.dt = TB_TYPE_INTN(cast(u16)(8*sz));
+				param.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
 				break;
 				break;
 
 
 			case Basic_f16: param.dt = TB_TYPE_F16; break;
 			case Basic_f16: param.dt = TB_TYPE_F16; break;
@@ -66,7 +66,7 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 				break;
 				break;
 
 
 			case Basic_typeid:
 			case Basic_typeid:
-				param.dt = TB_TYPE_INTN(cast(u16)(8*sz));
+				param.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
 				break;
 				break;
 
 
 			// Endian Specific Types
 			// Endian Specific Types
@@ -86,7 +86,7 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 			case Basic_u64be:
 			case Basic_u64be:
 			case Basic_i128be:
 			case Basic_i128be:
 			case Basic_u128be:
 			case Basic_u128be:
-				param.dt = TB_TYPE_INTN(cast(u16)(8*sz));
+				param.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
 				break;
 				break;
 
 
 			case Basic_f16le: param.dt = TB_TYPE_F16; break;
 			case Basic_f16le: param.dt = TB_TYPE_F16; break;
@@ -171,7 +171,7 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 			case Basic_int:
 			case Basic_int:
 			case Basic_uint:
 			case Basic_uint:
 			case Basic_uintptr:
 			case Basic_uintptr:
-				result.dt = TB_TYPE_INTN(cast(u16)(8*sz));
+				result.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
 				break;
 				break;
 
 
 			case Basic_f16: result.dt = TB_TYPE_I16; break;
 			case Basic_f16: result.dt = TB_TYPE_I16; break;
@@ -186,7 +186,7 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 				break;
 				break;
 
 
 			case Basic_typeid:
 			case Basic_typeid:
-				result.dt = TB_TYPE_INTN(cast(u16)(8*sz));
+				result.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
 				break;
 				break;
 
 
 			// Endian Specific Types
 			// Endian Specific Types
@@ -206,7 +206,7 @@ gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Ty
 			case Basic_u64be:
 			case Basic_u64be:
 			case Basic_i128be:
 			case Basic_i128be:
 			case Basic_u128be:
 			case Basic_u128be:
-				result.dt = TB_TYPE_INTN(cast(u16)(8*sz));
+				result.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
 				break;
 				break;
 
 
 			case Basic_f16le: result.dt = TB_TYPE_I16; break;
 			case Basic_f16le: result.dt = TB_TYPE_I16; break;
@@ -395,70 +395,75 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
 
 
 	GB_ASSERT(p->type->kind == Type_Proc);
 	GB_ASSERT(p->type->kind == Type_Proc);
 	TypeProc *pt = &p->type->Proc;
 	TypeProc *pt = &p->type->Proc;
-	if (pt->params) {
-		int param_index = 0;
-		for (Entity *e : pt->params->Tuple.variables) {
-			if (e->kind != Entity_Variable) {
-				continue;
-			}
-
-			if (param_index >= p->proto->param_count) {
-				break;
-			}
+	if (pt->params == nullptr) {
+		return;
+	}
+	int param_index = 0;
+	for (Entity *e : pt->params->Tuple.variables) {
+		if (e->kind != Entity_Variable) {
+			continue;
+		}
 
 
-			TB_Node *ptr = tb_inst_param_addr(p->func, param_index);
-			cgValue local = cg_value(ptr, alloc_type_pointer(e->type));
+		if (param_index >= p->proto->param_count) {
+			break;
+		}
 
 
-			if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") {
-				// NOTE(bill): for debugging purposes only
-				String name = e->token.string;
-				TB_DebugType *debug_type = cg_debug_type(p->module, e->type);
-				tb_node_append_attrib(ptr, tb_function_attrib_variable(p->func, name.len, cast(char const *)name.text, debug_type));
+		// TB_Node *ptr = tb_inst_param_addr(p->func, 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_DataType dt = cg_data_type(e->type);
+		tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false);
+		cgValue local = cg_value(ptr, alloc_type_pointer(e->type));
 
 
-			}
-			cgAddr addr = cg_addr(local);
-			if (e) {
-				map_set(&p->variable_map, e, addr);
-			}
+		if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") {
+			// NOTE(bill): for debugging purposes only
+			String name = e->token.string;
+			TB_DebugType *debug_type = cg_debug_type(p->module, e->type);
+			tb_node_append_attrib(ptr, tb_function_attrib_variable(p->func, name.len, cast(char const *)name.text, debug_type));
 
 
-			// if (arg_type->kind == lbArg_Ignore) {
-			// 	continue;
-			// } else if (arg_type->kind == lbArg_Direct) {
-			// 	if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
-			// 		LLVMTypeRef param_type = lb_type(p->module, e->type);
-			// 		LLVMValueRef original_value = LLVMGetParam(p->value, param_offset+param_index);
-			// 		LLVMValueRef value = OdinLLVMBuildTransmute(p, original_value, param_type);
-
-			// 		lbValue param = {};
-			// 		param.value = value;
-			// 		param.type = e->type;
-
-			// 		map_set(&p->direct_parameters, e, param);
-
-			// 		lbValue ptr = lb_address_from_load_or_generate_local(p, param);
-			// 		GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
-			// 		lb_add_entity(p->module, e, ptr);
-
-			// 		lbBlock *block = p->decl_block;
-			// 		if (original_value != value) {
-			// 			block = p->curr_block;
-			// 		}
-			// 		LLVMValueRef debug_storage_value = value;
-			// 		if (original_value != value && LLVMIsALoadInst(value)) {
-			// 			debug_storage_value = LLVMGetOperand(value, 0);
-			// 		}
-			// 		lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block, arg_type->kind);
-			// 	}
-			// } else if (arg_type->kind == lbArg_Indirect) {
-			// 	if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
-			// 		lbValue ptr = {};
-			// 		ptr.value = LLVMGetParam(p->value, param_offset+param_index);
-			// 		ptr.type = alloc_type_pointer(e->type);
-			// 		lb_add_entity(p->module, e, ptr);
-			// 		lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block, arg_type->kind);
-			// 	}
-			// }
 		}
 		}
+		cgAddr addr = cg_addr(local);
+		if (e) {
+			map_set(&p->variable_map, e, addr);
+		}
+
+		// if (arg_type->kind == lbArg_Ignore) {
+		// 	continue;
+		// } else if (arg_type->kind == lbArg_Direct) {
+		// 	if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
+		// 		LLVMTypeRef param_type = lb_type(p->module, e->type);
+		// 		LLVMValueRef original_value = LLVMGetParam(p->value, param_offset+param_index);
+		// 		LLVMValueRef value = OdinLLVMBuildTransmute(p, original_value, param_type);
+
+		// 		lbValue param = {};
+		// 		param.value = value;
+		// 		param.type = e->type;
+
+		// 		map_set(&p->direct_parameters, e, param);
+
+		// 		lbValue ptr = lb_address_from_load_or_generate_local(p, param);
+		// 		GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
+		// 		lb_add_entity(p->module, e, ptr);
+
+		// 		lbBlock *block = p->decl_block;
+		// 		if (original_value != value) {
+		// 			block = p->curr_block;
+		// 		}
+		// 		LLVMValueRef debug_storage_value = value;
+		// 		if (original_value != value && LLVMIsALoadInst(value)) {
+		// 			debug_storage_value = LLVMGetOperand(value, 0);
+		// 		}
+		// 		lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block, arg_type->kind);
+		// 	}
+		// } else if (arg_type->kind == lbArg_Indirect) {
+		// 	if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) {
+		// 		lbValue ptr = {};
+		// 		ptr.value = LLVMGetParam(p->value, param_offset+param_index);
+		// 		ptr.type = alloc_type_pointer(e->type);
+		// 		lb_add_entity(p->module, e, ptr);
+		// 		lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block, arg_type->kind);
+		// 	}
+		// }
 	}
 	}
 }
 }
 
 
@@ -466,7 +471,9 @@ gb_internal void cg_procedure_end(cgProcedure *p) {
 	if (p == nullptr || p->func == nullptr) {
 	if (p == nullptr || p->func == nullptr) {
 		return;
 		return;
 	}
 	}
-	tb_inst_ret(p->func, 0, nullptr);
+	if (tb_inst_get_control(p->func)) {
+		tb_inst_ret(p->func, 0, nullptr);
+	}
 	if (p->name == "main") {
 	if (p->name == "main") {
 		TB_Arena *arena = tb_default_arena();
 		TB_Arena *arena = tb_default_arena();
 		defer (arena->free(arena));
 		defer (arena->free(arena));

+ 27 - 1
src/tilde_stmt.cpp

@@ -736,7 +736,33 @@ gb_internal void cg_build_assign_stmt(cgProcedure *p, AstAssignStmt *as) {
 }
 }
 
 
 gb_internal void cg_build_return_stmt(cgProcedure *p, Slice<Ast *> const &return_results) {
 gb_internal void cg_build_return_stmt(cgProcedure *p, Slice<Ast *> const &return_results) {
-
+	TypeTuple *tuple  = &p->type->Proc.results->Tuple;
+	isize return_count = p->type->Proc.result_count;
+	gb_unused(tuple);
+	isize res_count = return_results.count;
+	gb_unused(res_count);
+
+	if (return_count == 0) {
+		tb_inst_ret(p->func, 0, nullptr);
+		return;
+	} else if (return_count == 1) {
+		Entity *e = tuple->variables[0];
+		if (res_count == 0) {
+			cgValue zero = cg_const_nil(p, tuple->variables[0]->type);
+			if (zero.kind == cgValue_Value) {
+				tb_inst_ret(p->func, 1, &zero.node);
+			}
+			return;
+		}
+		cgValue res = cg_build_expr(p, return_results[0]);
+		res = cg_emit_conv(p, res, e->type);
+		if (res.kind == cgValue_Value) {
+			tb_inst_ret(p->func, 1, &res.node);
+		}
+		return;
+	} else {
+		GB_PANIC("TODO(bill): MUTLIPLE RETURN VALUES");
+	}
 }
 }