Mock out struct_ep calls

This commit is contained in:
gingerBill
2023-07-17 17:28:12 +01:00
parent bd73834e19
commit b5b3f1fb42
2 changed files with 176 additions and 92 deletions
+1 -1
View File
@@ -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) // result = base + (index * stride)
TB_API TB_Node* tb_inst_array_access(TB_Function* f, TB_Node* base, TB_Node* index, int64_t 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 // where base is a pointer
TB_API TB_Node* tb_inst_member_access(TB_Function* f, TB_Node* base, int64_t offset); TB_API TB_Node* tb_inst_member_access(TB_Function* f, TB_Node* base, int64_t offset);
+175 -91
View File
@@ -325,84 +325,167 @@ gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) {
if (is_type_relative_pointer(t)) { if (is_type_relative_pointer(t)) {
s = cg_addr_get_ptr(p, cg_addr(s)); 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)) { switch (t->kind) {
result_type = get_struct_field_type(t, index); case Type_Struct:
} else if (is_type_union(t)) { {
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_ASSERT(index == -1);
GB_PANIC("TODO(bill): cg_emit_union_tag_ptr"); GB_PANIC("TODO(bill): cg_emit_union_tag_ptr");
break;
// return cg_emit_union_tag_ptr(p, s); // 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"); 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);
// return cg_emit_tuple_ep(p, s, index); case Type_Slice:
} else if (is_type_complex(t)) {
Type *ft = base_complex_elem_type(t);
switch (index) { switch (index) {
case 0: result_type = ft; break; case 0:
case 1: result_type = ft; break; 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_quaternion(t)) { break;
Type *ft = base_complex_elem_type(t); case Type_Basic:
switch (index) { switch (t->Basic.kind) {
case 0: result_type = ft; break; case Basic_string:
case 1: result_type = ft; break; switch (index) {
case 2: result_type = ft; break; case 0:
case 3: result_type = ft; break; result_type = t_u8_ptr;
} offset = 0;
} else if (is_type_slice(t)) { break;
switch (index) { case 1:
case 0: result_type = alloc_type_pointer(t->Slice.elem); break; result_type = t_int;
case 1: result_type = t_int; break; offset = int_size;
} break;
} else if (is_type_string(t)) { }
switch (index) { break;
case 0: result_type = t_u8_ptr; break; case Basic_any:
case 1: result_type = t_int; break; switch (index) {
} case 0:
} else if (is_type_any(t)) { result_type = t_rawptr;
switch (index) { offset = 0;
case 0: result_type = t_rawptr; break; break;
case 1: result_type = t_typeid; break; case 1:
} result_type = t_typeid;
} else if (is_type_dynamic_array(t)) { offset = ptr_size;
switch (index) { break;
case 0: result_type = alloc_type_pointer(t->DynamicArray.elem); break; }
case 1: result_type = t_int; break; break;
case 2: result_type = t_int; break;
case 3: result_type = t_allocator; break;
}
} 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);
switch (index) { case Basic_complex32:
case 0: result_type = get_struct_field_type(t_raw_map, 0); break; case Basic_complex64:
case 1: result_type = get_struct_field_type(t_raw_map, 1); break; case Basic_complex128:
case 2: result_type = get_struct_field_type(t_raw_map, 2); break; {
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_array(t)) { break;
case Type_DynamicArray:
switch (index) {
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;
}
break;
case Type_Map:
{
init_map_internal_types(t);
Type *itp = alloc_type_pointer(t_raw_map);
s = cg_emit_transmute(p, s, itp);
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;
}
case Type_Array:
return cg_emit_array_epi(p, s, index); return cg_emit_array_epi(p, s, index);
} else if (is_type_relative_slice(t)) { case Type_RelativeSlice:
switch (index) { {
case 0: result_type = t->RelativeSlice.base_integer; break; Type *bi = t->RelativeSlice.base_integer;
case 1: result_type = t->RelativeSlice.base_integer; break; 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) { switch (index) {
case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break; case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break;
case 1: result_type = t_int; 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); 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_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
GB_ASSERT(offset >= 0);
GB_PANIC("TODO(bill): cg_emit_struct_ep_internal"); GB_ASSERT(s.kind == cgValue_Value);
// return cg_emit_struct_ep_internal(p, s, index, result_type); return cg_value(
return {}; 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) { 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); 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 addr = cg_emit_struct_ep(p, e, 0);
cgValue index = cg_emit_struct_ep(p, e, 1); cgValue index = cg_emit_struct_ep(p, e, 1);
addr = cg_emit_load(p, addr); addr = cg_emit_load(p, addr);
@@ -438,25 +522,11 @@ gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection
} else { } else {
e = cg_emit_ptr_offset(p, cg_emit_load(p, arr), index); e = cg_emit_ptr_offset(p, cg_emit_load(p, arr), index);
} }
} else if (is_type_quaternion(type)) { break;
e = cg_emit_struct_ep(p, e, index); }
} else if (is_type_raw_union(type)) { case Type_Basic:
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) {
switch (type->Basic.kind) { switch (type->Basic.kind) {
case Basic_any: { case Basic_any:
if (index == 0) { if (index == 0) {
type = t_rawptr; type = t_rawptr;
} else if (index == 1) { } 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); e = cg_emit_struct_ep(p, e, index);
break; break;
} default:
case Basic_string:
e = cg_emit_struct_ep(p, e, index); e = cg_emit_struct_ep(p, e, index);
break; break;
default:
GB_PANIC("un-gep-able type %s", type_to_string(type));
break;
} }
} else if (type->kind == Type_Slice) { 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); e = cg_emit_struct_ep(p, e, index);
} else if (type->kind == Type_DynamicArray) { break;
case Type_Tuple:
type = type->Tuple.variables[index]->type;
e = cg_emit_struct_ep(p, e, index); e = cg_emit_struct_ep(p, e, index);
} else if (type->kind == Type_Array) { break;
case Type_Slice:
case Type_DynamicArray:
case Type_Map:
case Type_RelativePointer:
e = cg_emit_struct_ep(p, e, index);
break;
case Type_Array:
e = cg_emit_array_epi(p, e, index); e = cg_emit_array_epi(p, e, index);
} else if (type->kind == Type_Map) { break;
e = cg_emit_struct_ep(p, e, index); default:
} else if (type->kind == Type_RelativePointer) {
e = cg_emit_struct_ep(p, e, index);
} else {
GB_PANIC("un-gep-able type %s", type_to_string(type)); GB_PANIC("un-gep-able type %s", type_to_string(type));
break;
} }
} }