Browse Source

Mock out struct_ep calls

gingerBill 2 years ago
parent
commit
b5b3f1fb42
2 changed files with 173 additions and 89 deletions
  1. 1 1
      src/tilde/tb.h
  2. 172 88
      src/tilde_stmt.cpp

+ 1 - 1
src/tilde/tb.h

@@ -941,7 +941,7 @@ TB_API void tb_inst_memcpy(TB_Function* f, TB_Node* dst, TB_Node* src, TB_Node*
 // result = base + (index * stride)
 TB_API TB_Node* tb_inst_array_access(TB_Function* f, TB_Node* base, TB_Node* index, int64_t stride);
 
-// result = base + offset
+// result = base +
 // where base is a pointer
 TB_API TB_Node* tb_inst_member_access(TB_Function* f, TB_Node* base, int64_t offset);
 

+ 172 - 88
src/tilde_stmt.cpp

@@ -325,84 +325,167 @@ gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) {
 	if (is_type_relative_pointer(t)) {
 		s = cg_addr_get_ptr(p, cg_addr(s));
 	}
+	i64 offset = -1;
+	i64 int_size = build_context.int_size;
+	i64 ptr_size = build_context.ptr_size;
 
-	if (is_type_struct(t)) {
-		result_type = get_struct_field_type(t, index);
-	} else if (is_type_union(t)) {
+	switch (t->kind) {
+	case Type_Struct:
+		{
+			type_set_offsets(t);
+			result_type = t->Struct.fields[index]->type;
+			offset = t->Struct.offsets[index];
+		}
+		break;
+	case Type_Union:
 		GB_ASSERT(index == -1);
 		GB_PANIC("TODO(bill): cg_emit_union_tag_ptr");
+		break;
 		// return cg_emit_union_tag_ptr(p, s);
-	} else if (is_type_tuple(t)) {
+	case Type_Tuple:
 		GB_PANIC("TODO(bill): cg_emit_tuple_ep");
+		break;
 		// return cg_emit_tuple_ep(p, s, index);
-		// return cg_emit_tuple_ep(p, s, index);
-	} else if (is_type_complex(t)) {
-		Type *ft = base_complex_elem_type(t);
+	case Type_Slice:
 		switch (index) {
-		case 0: result_type = ft; break;
-		case 1: result_type = ft; break;
-		}
-	} else if (is_type_quaternion(t)) {
-		Type *ft = base_complex_elem_type(t);
-		switch (index) {
-		case 0: result_type = ft; break;
-		case 1: result_type = ft; break;
-		case 2: result_type = ft; break;
-		case 3: result_type = ft; break;
-		}
-	} else if (is_type_slice(t)) {
-		switch (index) {
-		case 0: result_type = alloc_type_pointer(t->Slice.elem); break;
-		case 1: result_type = t_int; break;
-		}
-	} else if (is_type_string(t)) {
-		switch (index) {
-		case 0: result_type = t_u8_ptr; break;
-		case 1: result_type = t_int;    break;
+		case 0:
+			result_type = alloc_type_pointer(t->Slice.elem);
+			offset = 0;
+			break;
+		case 1:
+			result_type = t_int;
+			offset = int_size;
+			break;
 		}
-	} else if (is_type_any(t)) {
-		switch (index) {
-		case 0: result_type = t_rawptr; break;
-		case 1: result_type = t_typeid; break;
+		break;
+	case Type_Basic:
+		switch (t->Basic.kind) {
+		case Basic_string:
+			switch (index) {
+			case 0:
+				result_type = t_u8_ptr;
+				offset = 0;
+				break;
+			case 1:
+				result_type = t_int;
+				offset = int_size;
+				break;
+			}
+			break;
+		case Basic_any:
+			switch (index) {
+			case 0:
+				result_type = t_rawptr;
+				offset = 0;
+				break;
+			case 1:
+				result_type = t_typeid;
+				offset = ptr_size;
+				break;
+			}
+			break;
+
+		case Basic_complex32:
+		case Basic_complex64:
+		case Basic_complex128:
+			{
+				Type *ft = base_complex_elem_type(t);
+				i64 sz = type_size_of(ft);
+				switch (index) {
+				case 0: case 1:
+					result_type = ft; offset = sz * index; break;
+				default: goto error_case;
+				}
+				break;
+			}
+		case Basic_quaternion64:
+		case Basic_quaternion128:
+		case Basic_quaternion256:
+			{
+				Type *ft = base_complex_elem_type(t);
+				i64 sz = type_size_of(ft);
+				switch (index) {
+				case 0: case 1: case 2: case 3:
+					result_type = ft; offset = sz * index; break;
+				default: goto error_case;
+				}
+			}
+			break;
+		default:
+			goto error_case;
 		}
-	} else if (is_type_dynamic_array(t)) {
+		break;
+	case Type_DynamicArray:
 		switch (index) {
-		case 0: result_type = alloc_type_pointer(t->DynamicArray.elem); break;
-		case 1: result_type = t_int;       break;
-		case 2: result_type = t_int;       break;
-		case 3: result_type = t_allocator; break;
+		case 0:
+			result_type = alloc_type_pointer(t->DynamicArray.elem);
+			offset = index*int_size;
+			break;
+		case 1: case 2:
+			result_type = t_int;
+			offset = index*int_size;
+			break;
+		case 3:
+			result_type = t_allocator;
+			offset = index*int_size;
+			break;
+		default: goto error_case;
 		}
-	} else if (is_type_map(t)) {
-		init_map_internal_types(t);
-		Type *itp = alloc_type_pointer(t_raw_map);
-		s = cg_emit_transmute(p, s, itp);
+		break;
+	case Type_Map:
+		{
+			init_map_internal_types(t);
+			Type *itp = alloc_type_pointer(t_raw_map);
+			s = cg_emit_transmute(p, s, itp);
 
-		switch (index) {
-		case 0: result_type = get_struct_field_type(t_raw_map, 0); break;
-		case 1: result_type = get_struct_field_type(t_raw_map, 1); break;
-		case 2: result_type = get_struct_field_type(t_raw_map, 2); break;
+			Type *rms = base_type(t_raw_map);
+			GB_ASSERT(rms->kind == Type_Struct);
+
+			if (0 <= index && index < 3) {
+				result_type = rms->Struct.fields[index]->type;
+				offset = rms->Struct.offsets[index];
+			} else {
+				goto error_case;
+			}
+			break;
 		}
-	} else if (is_type_array(t)) {
+	case Type_Array:
 		return cg_emit_array_epi(p, s, index);
-	} else if (is_type_relative_slice(t)) {
-		switch (index) {
-		case 0: result_type = t->RelativeSlice.base_integer; break;
-		case 1: result_type = t->RelativeSlice.base_integer; break;
+	case Type_RelativeSlice:
+		{
+			Type *bi = t->RelativeSlice.base_integer;
+			i64 sz = type_size_of(bi);
+			switch (index) {
+			case 0:
+			case 1:
+				result_type = bi;
+				offset = sz * index;
+				break;
+			default:
+				goto error_case;
+			}
 		}
-	} else if (is_type_soa_pointer(t)) {
+		break;
+	case Type_SoaPointer:
 		switch (index) {
 		case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break;
 		case 1: result_type = t_int; break;
 		}
-	} else {
+		break;
+	default:
+	error_case:;
 		GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(s.type), index);
+		break;
 	}
 
 	GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
+	GB_ASSERT(offset >= 0);
 
-	GB_PANIC("TODO(bill): cg_emit_struct_ep_internal");
-	// return cg_emit_struct_ep_internal(p, s, index, result_type);
-	return {};
+	GB_ASSERT(s.kind == cgValue_Value);
+	return cg_value(
+		tb_inst_member_access(p->func, s.node, offset),
+		alloc_type_pointer(result_type)
+	);
 }
 
 gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection const &sel) {
@@ -417,7 +500,8 @@ gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection
 		}
 		type = core_type(type);
 
-		if (type->kind == Type_SoaPointer) {
+		switch (type->kind) {
+		case Type_SoaPointer: {
 			cgValue addr = cg_emit_struct_ep(p, e, 0);
 			cgValue index = cg_emit_struct_ep(p, e, 1);
 			addr = cg_emit_load(p, addr);
@@ -438,25 +522,11 @@ gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection
 			} else {
 				e = cg_emit_ptr_offset(p, cg_emit_load(p, arr), index);
 			}
-		} else if (is_type_quaternion(type)) {
-			e = cg_emit_struct_ep(p, e, index);
-		} else if (is_type_raw_union(type)) {
-			type = get_struct_field_type(type, index);
-			GB_ASSERT(is_type_pointer(e.type));
-			e = cg_emit_transmute(p, e, alloc_type_pointer(type));
-		} else if (is_type_struct(type)) {
-			type = get_struct_field_type(type, index);
-			e = cg_emit_struct_ep(p, e, index);
-		} else if (type->kind == Type_Union) {
-			GB_ASSERT(index == -1);
-			type = t_type_info_ptr;
-			e = cg_emit_struct_ep(p, e, index);
-		} else if (type->kind == Type_Tuple) {
-			type = type->Tuple.variables[index]->type;
-			e = cg_emit_struct_ep(p, e, index);
-		} else if (type->kind == Type_Basic) {
+			break;
+		}
+		case Type_Basic:
 			switch (type->Basic.kind) {
-			case Basic_any: {
+			case Basic_any:
 				if (index == 0) {
 					type = t_rawptr;
 				} else if (index == 1) {
@@ -464,28 +534,42 @@ gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection
 				}
 				e = cg_emit_struct_ep(p, e, index);
 				break;
-			}
-
-			case Basic_string:
-				e = cg_emit_struct_ep(p, e, index);
-				break;
-
 			default:
-				GB_PANIC("un-gep-able type %s", type_to_string(type));
+				e = cg_emit_struct_ep(p, e, index);
 				break;
 			}
-		} else if (type->kind == Type_Slice) {
-			e = cg_emit_struct_ep(p, e, index);
-		} else if (type->kind == Type_DynamicArray) {
+			break;
+		case Type_Struct:
+			if (type->Struct.is_raw_union) {
+				type = get_struct_field_type(type, index);
+				GB_ASSERT(is_type_pointer(e.type));
+				e = cg_emit_transmute(p, e, alloc_type_pointer(type));
+			} else {
+				type = get_struct_field_type(type, index);
+				e = cg_emit_struct_ep(p, e, index);
+			}
+			break;
+		case Type_Union:
+			GB_ASSERT(index == -1);
+			type = t_type_info_ptr;
 			e = cg_emit_struct_ep(p, e, index);
-		} else if (type->kind == Type_Array) {
-			e = cg_emit_array_epi(p, e, index);
-		} else if (type->kind == Type_Map) {
+			break;
+		case Type_Tuple:
+			type = type->Tuple.variables[index]->type;
 			e = cg_emit_struct_ep(p, e, index);
-		} else if (type->kind == Type_RelativePointer) {
+			break;
+		case Type_Slice:
+		case Type_DynamicArray:
+		case Type_Map:
+		case Type_RelativePointer:
 			e = cg_emit_struct_ep(p, e, index);
-		} else {
+			break;
+		case Type_Array:
+			e = cg_emit_array_epi(p, e, index);
+			break;
+		default:
 			GB_PANIC("un-gep-able type %s", type_to_string(type));
+			break;
 		}
 	}