diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 7d2f574fe..5108e7c39 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1626,6 +1626,8 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { GB_ASSERT(type != t_invalid); + bool bigger_int = build_context.word_size != build_context.int_size; + switch (type->kind) { case Type_Basic: switch (type->Basic.kind) { @@ -1760,8 +1762,8 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { return type; } - case Basic_int: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size); - case Basic_uint: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size); + case Basic_int: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size); + case Basic_uint: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size); case Basic_uintptr: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size); @@ -1922,23 +1924,43 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_Slice: { - LLVMTypeRef fields[2] = { - LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data - lb_type(m, t_int), // len - }; - return LLVMStructTypeInContext(ctx, fields, 2, false); + if (bigger_int) { + LLVMTypeRef fields[3] = { + LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data + lb_type_padding_filler(m, build_context.word_size, build_context.word_size), // padding + lb_type(m, t_int), // len + }; + return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false); + } else { + LLVMTypeRef fields[2] = { + LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data + lb_type(m, t_int), // len + }; + return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false); + } } break; case Type_DynamicArray: { - LLVMTypeRef fields[4] = { - LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data - lb_type(m, t_int), // len - lb_type(m, t_int), // cap - lb_type(m, t_allocator), // allocator - }; - return LLVMStructTypeInContext(ctx, fields, 4, false); + if (bigger_int) { + LLVMTypeRef fields[5] = { + LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data + lb_type_padding_filler(m, build_context.word_size, build_context.word_size), // padding + lb_type(m, t_int), // len + lb_type(m, t_int), // cap + lb_type(m, t_allocator), // allocator + }; + return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false); + } else { + LLVMTypeRef fields[4] = { + LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data + lb_type(m, t_int), // len + lb_type(m, t_int), // cap + lb_type(m, t_allocator), // allocator + }; + return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false); + } } break; @@ -2145,9 +2167,17 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_SoaPointer: { unsigned field_count = 2; + if (bigger_int) { + field_count = 3; + } LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count); fields[0] = LLVMPointerType(lb_type(m, type->Pointer.elem), 0); - fields[1] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size); + if (bigger_int) { + fields[1] = lb_type_padding_filler(m, build_context.word_size, build_context.word_size); + fields[2] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size); + } else { + fields[1] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size); + } return LLVMStructTypeInContext(ctx, fields, field_count, false); } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index ddae2243b..99deca5e9 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -929,7 +929,33 @@ gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) gb_internal i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) { if (t->kind == Type_Struct) { auto field_remapping = lb_get_struct_remapping(m, t); - index = field_remapping[index]; + return field_remapping[index]; + } else if (build_context.word_size != build_context.int_size) { + switch (t->kind) { + case Type_Slice: + GB_ASSERT(build_context.word_size*2 == build_context.int_size); + switch (index) { + case 0: return 0; // data + case 1: return 2; // len + } + break; + case Type_DynamicArray: + GB_ASSERT(build_context.word_size*2 == build_context.int_size); + switch (index) { + case 0: return 0; // data + case 1: return 2; // len + case 2: return 3; // cap + case 3: return 4; // allocator + } + break; + case Type_SoaPointer: + GB_ASSERT(build_context.word_size*2 == build_context.int_size); + switch (index) { + case 0: return 0; // data + case 1: return 2; // offset + } + break; + } } return index; }