diff options
| author | gingerBill <bill@gingerbill.org> | 2021-04-25 19:56:46 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-04-25 19:56:46 +0100 |
| commit | 6383714bffb05a34a5320a757e08dd73bf9a2b0c (patch) | |
| tree | b2b06c06315d939a95ba4b93355e8d2495e800cd /src/check_type.cpp | |
| parent | a25e796b0016dbf180492ef660d0abcc023f5d56 (diff) | |
Remove old procedure ABI code
Diffstat (limited to 'src/check_type.cpp')
| -rw-r--r-- | src/check_type.cpp | 618 |
1 files changed, 0 insertions, 618 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp index e3aac161c..aef1ddc7a 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1162,9 +1162,6 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper } if (is_polymorphic_type_assignable(ctx, poly_type, operand.type, false, modify_type)) { - if (show_error) { - set_procedure_abi_types(poly_type); - } return poly_type; } if (show_error) { @@ -1767,623 +1764,8 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { return tuple; } -Array<Type *> systemv_distribute_struct_fields(Type *t) { - Type *bt = core_type(t); - - - isize distributed_cap = 1; - if (bt->kind == Type_Struct) { - distributed_cap = bt->Struct.fields.count; - } - auto distributed = array_make<Type *>(heap_allocator(), 0, distributed_cap); - - i64 sz = type_size_of(bt); - switch (bt->kind) { - case Type_Basic: - switch (bt->Basic.kind){ - case Basic_complex64: - array_add(&distributed, t_f32); - array_add(&distributed, t_f32); - break; - case Basic_complex128: - array_add(&distributed, t_f64); - array_add(&distributed, t_f64); - break; - case Basic_quaternion128: - array_add(&distributed, t_f32); - array_add(&distributed, t_f32); - array_add(&distributed, t_f32); - array_add(&distributed, t_f32); - break; - case Basic_quaternion256: - goto DEFAULT; - case Basic_string: - array_add(&distributed, t_u8_ptr); - array_add(&distributed, t_int); - break; - case Basic_any: - GB_ASSERT(type_size_of(t_uintptr) == type_size_of(t_typeid)); - array_add(&distributed, t_rawptr); - array_add(&distributed, t_uintptr); - break; - - case Basic_u128: - case Basic_i128: - if (build_context.ODIN_OS == "windows") { - array_add(&distributed, alloc_type_simd_vector(2, t_u64)); - } else { - array_add(&distributed, bt); - } - break; - - default: - goto DEFAULT; - } - break; - - case Type_Struct: - if (bt->Struct.is_raw_union) { - goto DEFAULT; - } else { - // IMPORTANT TOOD(bill): handle #packed structs correctly - // IMPORTANT TODO(bill): handle #align structs correctly - for_array(field_index, bt->Struct.fields) { - Entity *f = bt->Struct.fields[field_index]; - auto nested = systemv_distribute_struct_fields(f->type); - array_add_elems(&distributed, nested.data, nested.count); - array_free(&nested); - } - } - break; - - case Type_Array: - for (i64 i = 0; i < bt->Array.count; i++) { - array_add(&distributed, bt->Array.elem); - } - break; - - case Type_BitSet: - array_add(&distributed, bit_set_to_int(bt)); - break; - - case Type_Tuple: - GB_PANIC("Invalid struct field type"); - break; - - case Type_Slice: - array_add(&distributed, t_rawptr); - array_add(&distributed, t_int); - break; - - case Type_Union: - case Type_DynamicArray: - case Type_Map: - // NOTE(bill, 2019-10-10): Odin specific, don't worry about C calling convention yet - goto DEFAULT; - - case Type_Pointer: - case Type_Proc: - case Type_SimdVector: // TODO(bill): Is this correct logic? - default: - DEFAULT:; - if (sz > 0) { - array_add(&distributed, bt); - } - break; - } - - return distributed; -} - -Type *struct_type_from_systemv_distribute_struct_fields(Type *abi_type) { - GB_ASSERT(is_type_tuple(abi_type)); - Type *final_type = alloc_type_struct(); - final_type->Struct.fields = abi_type->Tuple.variables; - return final_type; -} - - -Type *handle_single_distributed_type_parameter(Array<Type *> const &types, bool packed, isize *offset) { - GB_ASSERT(types.count > 0); - - if (types.count == 1) { - if (offset) *offset = 1; - - i64 sz = type_size_of(types[0]); - - if (is_type_float(types[0])) { - return types[0]; - } - switch (sz) { - case 0: - GB_PANIC("Zero sized type found!"); - case 1: return t_u8; - case 2: return t_u16; - case 4: return t_u32; - case 8: return t_u64; - default: - return types[0]; - } - } else if (types.count >= 2) { - if (types[0] == t_f32 && types[1] == t_f32) { - if (offset) *offset = 2; - return alloc_type_simd_vector(2, t_f32); - } else if (type_size_of(types[0]) == 8) { - if (offset) *offset = 1; - return types[0]; - } - - i64 total_size = 0; - isize i = 0; - if (packed) { - for (; i < types.count && total_size < 8; i += 1) { - Type *t = types[i]; - i64 s = type_size_of(t); - total_size += s; - } - } else { - for (; i < types.count && total_size < 8; i += 1) { - Type *t = types[i]; - i64 s = gb_max(type_size_of(t), 0); - i64 a = gb_max(type_align_of(t), 1); - isize ts = align_formula(total_size, a); - if (ts >= 8) { - break; - } - total_size = ts + s; - } - } - if (offset) *offset = i; - switch (total_size) { - case 1: return t_u8; - case 2: return t_u16; - case 4: return t_u32; - case 8: return t_u64; - } - return t_u64; - } - - return nullptr; -} - -Type *handle_struct_system_v_amd64_abi_type(Type *t) { - if (type_size_of(t) > 16) { - return alloc_type_pointer(t); - } - Type *original_type = t; - Type *bt = core_type(t); - t = base_type(t); - i64 size = type_size_of(bt); - - switch (t->kind) { - case Type_Slice: - case Type_Struct: - break; - - case Type_Basic: - switch (bt->Basic.kind) { - case Basic_string: - case Basic_any: - case Basic_complex64: - case Basic_complex128: - case Basic_quaternion128: - break; - default: - return original_type; - } - break; - - default: - return original_type; - } - - bool is_packed = false; - if (is_type_struct(bt)) { - is_packed = bt->Struct.is_packed; - } - - if (is_type_raw_union(bt)) { - // TODO(bill): Handle raw union correctly for - return t; - } else { - auto field_types = systemv_distribute_struct_fields(bt); - defer (array_free(&field_types)); - - GB_ASSERT(field_types.count <= 16); - - Type *final_type = nullptr; - - if (field_types.count == 0) { - final_type = t; - } else if (field_types.count == 1) { - final_type = field_types[0]; - } else { - if (size <= 8) { - isize offset = 0; - final_type = handle_single_distributed_type_parameter(field_types, is_packed, &offset); - } else { - isize offset = 0; - isize next_offset = 0; - Type *two_types[2] = {}; - - two_types[0] = handle_single_distributed_type_parameter(field_types, is_packed, &offset); - auto remaining = array_slice(field_types, offset, field_types.count); - two_types[1] = handle_single_distributed_type_parameter(remaining, is_packed, &next_offset); - GB_ASSERT(offset + next_offset == field_types.count); - - auto variables = array_make<Entity *>(heap_allocator(), 2); - variables[0] = alloc_entity_param(nullptr, empty_token, two_types[0], false, false); - variables[1] = alloc_entity_param(nullptr, empty_token, two_types[1], false, false); - final_type = alloc_type_tuple(); - final_type->Tuple.variables = variables; - if (t->kind == Type_Struct) { - // NOTE(bill): Make this packed - final_type->Tuple.is_packed = t->Struct.is_packed; - } - } - } - - - GB_ASSERT(final_type != nullptr); - i64 ftsz = type_size_of(final_type); - i64 otsz = type_size_of(original_type); - if (ftsz != otsz) { - // TODO(bill): Handle this case which will be caused by #packed most likely - switch (otsz) { - case 1: - case 2: - case 4: - case 8: - GB_PANIC("Incorrectly handled case for handle_struct_system_v_amd64_abi_type, %s %lld vs %s %lld", type_to_string(final_type), ftsz, type_to_string(original_type), otsz); - } - } - - return final_type; - } -} -Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type, ProcCallingConvention cc) { - Type *new_type = original_type; - if (is_type_boolean(original_type)) { - Type *t = core_type(base_type(new_type)); - if (t == t_bool) { - return t_llvm_bool; - } - return new_type; - } - - if (is_type_proc(original_type)) { - // NOTE(bill): Force a cast to prevent a possible type cycle - return t_rawptr; - } - - if (is_calling_convention_none(cc)) { - return new_type; - } - - if (build_context.ODIN_ARCH == "386") { - return new_type; - } - - if (is_type_simd_vector(original_type)) { - return new_type; - } - if (build_context.ODIN_ARCH == "amd64") { - bool is_128 = is_type_integer_128bit(original_type); - if (!is_128 && is_type_bit_set(original_type) && type_size_of(original_type) == 16) { - // is_128 = true; - } - if (is_128) { - if (build_context.ODIN_OS == "windows") { - return alloc_type_simd_vector(2, t_u64); - } else { - return original_type; - } - } - } - - if (build_context.ODIN_OS == "windows") { - // NOTE(bill): Changing the passing parameter value type is to match C's ABI - // IMPORTANT TODO(bill): This only matches the ABI on MSVC at the moment - // SEE: https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx - - - Type *bt = core_type(original_type); - switch (bt->kind) { - // Okay to pass by value (usually) - // Especially the only Odin types - case Type_Basic: { - i64 sz = bt->Basic.size; - // if (sz > 8 && build_context.word_size < 8) { - if (sz > 8) { - new_type = alloc_type_pointer(original_type); - } - break; - } - case Type_Pointer: - if (is_type_struct(bt->Pointer.elem)) { - // Force to a raw pointer - new_type = t_rawptr; - } - break; - case Type_Proc: - new_type = t_rawptr; - break; // NOTE(bill): Just a pointer - - // Odin specific - case Type_Slice: - case Type_Array: - case Type_DynamicArray: - case Type_Map: - case Type_Union: - // Could be in C too - case Type_Struct: - { - i64 align = type_align_of(original_type); - i64 size = type_size_of(original_type); - - switch (8*size) { - case 8: new_type = t_u8; break; - case 16: new_type = t_u16; break; - case 32: new_type = t_u32; break; - case 64: new_type = t_u64; break; - default: - new_type = alloc_type_pointer(original_type); - break; - } - - break; - } - } - } else if (build_context.ODIN_OS == "linux" || - build_context.ODIN_OS == "darwin") { - Type *bt = core_type(original_type); - switch (bt->kind) { - // Okay to pass by value (usually) - // Especially the only Odin types - case Type_Basic: { - i64 sz = bt->Basic.size; - // if (sz > 8 && build_context.word_size < 8) { - if (sz > 8) { - new_type = alloc_type_pointer(original_type); - } - - break; - } - case Type_Pointer: break; - case Type_Proc: break; // NOTE(bill): Just a pointer - - default: { - i64 size = type_size_of(original_type); - if (size > 16) { - new_type = alloc_type_pointer(original_type); - } else if (build_context.ODIN_ARCH == "amd64") { - // NOTE(bill): System V AMD64 ABI - new_type = handle_struct_system_v_amd64_abi_type(bt); - if (are_types_identical(core_type(original_type), new_type)) { - new_type = original_type; - } - return new_type; - } - - break; - } - } - } else { - // IMPORTANT TODO(bill): figure out the ABI settings for Linux, OSX etc. for - // their architectures - } - - return new_type; -} - - -Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type, ProcCallingConvention cc) { - Type *new_type = original_type; - if (new_type == nullptr) { - return nullptr; - } - GB_ASSERT(is_type_tuple(original_type)); - - Type *single_type = reduce_tuple_to_single_type(original_type); - - if (cc == ProcCC_InlineAsm) { - return new_type; - } - - if (is_type_proc(single_type)) { - // NOTE(bill): Force a cast to prevent a possible type cycle - return t_rawptr; - } - - if (is_type_simd_vector(single_type)) { - return new_type; - } - - if (is_type_pointer(single_type)) { - // NOTE(bill): Force a cast to prevent a possible type cycle - return t_rawptr; - } - - if (build_context.ODIN_OS == "windows") { - if (build_context.ODIN_ARCH == "amd64") { - if (is_type_integer_128bit(single_type)) { - if (is_calling_convention_none(cc)) { - return original_type; - } else { - return alloc_type_simd_vector(2, t_u64); - } - } - } - - Type *bt = core_type(reduce_tuple_to_single_type(original_type)); - // NOTE(bill): This is just reversed engineered from LLVM IR output - switch (bt->kind) { - // Okay to pass by value - // Especially the only Odin types - case Type_Pointer: break; - case Type_Proc: break; // NOTE(bill): Just a pointer - case Type_Basic: break; - - - default: { - i64 align = type_align_of(original_type); - i64 size = type_size_of(original_type); - switch (8*size) { -#if 1 - case 8: new_type = t_u8; break; - case 16: new_type = t_u16; break; - case 32: new_type = t_u32; break; - case 64: new_type = t_u64; break; -#endif - } - - break; - } - } - } else if (build_context.ODIN_OS == "linux" || build_context.ODIN_OS == "darwin") { - if (build_context.ODIN_ARCH == "amd64") { - - } - } else { - // IMPORTANT TODO(bill): figure out the ABI settings for Linux, OSX etc. for - // their architectures - } - - if (is_type_integer_128bit(single_type)) { - if (build_context.word_size == 8) { - return original_type; - } - } - - - if (new_type != original_type) { - Type *tuple = alloc_type_tuple(); - auto variables = array_make<Entity *>(a, 0, 1); - array_add(&variables, alloc_entity_param(original_type->Tuple.variables[0]->scope, empty_token, new_type, false, false)); - tuple->Tuple.variables = variables; - new_type = tuple; - } - - if (cc == ProcCC_None) { - for_array(i, new_type->Tuple.variables) { - Type **tp = &new_type->Tuple.variables[i]->type; - Type *t = core_type(*tp); - if (t == t_bool) { - *tp = t_llvm_bool; - } - } - } - - new_type->cached_size = -1; - new_type->cached_align = -1; - return new_type; -} - -bool abi_compat_return_by_pointer(gbAllocator a, ProcCallingConvention cc, Type *abi_return_type) { - if (abi_return_type == nullptr) { - return false; - } - if (is_calling_convention_none(cc)) { - return false; - } - - Type *single_type = reduce_tuple_to_single_type(abi_return_type); - - if (is_type_simd_vector(single_type)) { - return false; - } - - if (build_context.word_size == 8) { - if (is_type_integer_128bit(single_type)) { - return false; - } - } - - if (build_context.ODIN_OS == "windows" || build_context.ODIN_OS == "linux" ) { - i64 size = 8*type_size_of(abi_return_type); - switch (size) { - case 0: - case 8: - case 16: - case 32: - case 64: - return false; - default: - return true; - } - } else { - if (is_type_integer_128bit(single_type)) { - return build_context.word_size < 8; - } - } - - - - return false; -} - -void set_procedure_abi_types(Type *type) { - type = base_type(type); - if (type->kind != Type_Proc) { - return; - } - - if (type->Proc.abi_types_set || type->flags & TypeFlag_InProcessOfCheckingABI) { - return; - } - - gbAllocator allocator = permanent_allocator(); - - u32 flags = type->flags; - type->flags |= TypeFlag_InProcessOfCheckingABI; - - type->Proc.abi_compat_params = array_make<Type *>(allocator, cast(isize)type->Proc.param_count); - for (i32 i = 0; i < type->Proc.param_count; i++) { - Entity *e = type->Proc.params->Tuple.variables[i]; - if (e->kind == Entity_Variable) { - Type *original_type = e->type; - Type *new_type = type_to_abi_compat_param_type(allocator, original_type, type->Proc.calling_convention); - type->Proc.abi_compat_params[i] = new_type; - switch (type->Proc.calling_convention) { - case ProcCC_Odin: - case ProcCC_Contextless: - if (is_type_pointer(new_type) && !is_type_pointer(e->type) && !is_type_proc(e->type)) { - e->flags |= EntityFlag_ImplicitReference; - } - break; - } - - if (build_context.ODIN_OS == "linux" || - build_context.ODIN_OS == "darwin") { - if (is_type_pointer(new_type) & !is_type_pointer(e->type) && !is_type_proc(e->type)) { - e->flags |= EntityFlag_ByVal; - } - } - } - } - - for (i32 i = 0; i < type->Proc.param_count; i++) { - Entity *e = type->Proc.params->Tuple.variables[i]; - if (e->kind == Entity_Variable) { - set_procedure_abi_types(e->type); - } - } - for (i32 i = 0; i < type->Proc.result_count; i++) { - Entity *e = type->Proc.results->Tuple.variables[i]; - if (e->kind == Entity_Variable) { - set_procedure_abi_types(e->type); - } - } - - // NOTE(bill): The types are the same - type->Proc.abi_compat_result_type = type_to_abi_compat_result_type(allocator, type->Proc.results, type->Proc.calling_convention); - type->Proc.return_by_pointer = abi_compat_return_by_pointer(allocator, type->Proc.calling_convention, type->Proc.abi_compat_result_type); - - type->Proc.abi_types_set = true; - type->flags = flags; -} // NOTE(bill): 'operands' is for generating non generic procedure type bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array<Operand> *operands) { |