| ... | @@ -845,9 +845,11 @@ pub const DeclGen = struct { | ... | @@ -845,9 +845,11 @@ pub const DeclGen = struct { |
| 845 | defer llvm_field_types.deinit(gpa); | 845 | defer llvm_field_types.deinit(gpa); |
| 846 | | 846 | |
| 847 | if (struct_obj.layout == .Packed) { | 847 | if (struct_obj.layout == .Packed) { |
| | 848 | try llvm_field_types.ensureUnusedCapacity(gpa, struct_obj.fields.count() * 2); |
| 848 | const target = dg.module.getTarget(); | 849 | const target = dg.module.getTarget(); |
| 849 | comptime assert(Type.packed_struct_layout_version == 1); | 850 | comptime assert(Type.packed_struct_layout_version == 1); |
| 850 | var offset: u64 = 0; | 851 | var offset: u64 = 0; |
| | 852 | var big_align: u32 = 0; |
| 851 | var running_bits: u16 = 0; | 853 | var running_bits: u16 = 0; |
| 852 | for (struct_obj.fields.values()) |field| { | 854 | for (struct_obj.fields.values()) |field| { |
| 853 | if (!field.ty.hasCodeGenBits()) continue; | 855 | if (!field.ty.hasCodeGenBits()) continue; |
| ... | @@ -863,6 +865,7 @@ pub const DeclGen = struct { | ... | @@ -863,6 +865,7 @@ pub const DeclGen = struct { |
| 863 | }; | 865 | }; |
| 864 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; | 866 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; |
| 865 | const int_align = int_ty.abiAlignment(target); | 867 | const int_align = int_ty.abiAlignment(target); |
| | 868 | big_align = @maximum(big_align, int_align); |
| 866 | const llvm_int_ty = try dg.llvmType(int_ty); | 869 | const llvm_int_ty = try dg.llvmType(int_ty); |
| 867 | const prev_offset = offset; | 870 | const prev_offset = offset; |
| 868 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); | 871 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); |
| ... | @@ -875,6 +878,7 @@ pub const DeclGen = struct { | ... | @@ -875,6 +878,7 @@ pub const DeclGen = struct { |
| 875 | offset += int_ty.abiSize(target); | 878 | offset += int_ty.abiSize(target); |
| 876 | running_bits = 0; | 879 | running_bits = 0; |
| 877 | } | 880 | } |
| | 881 | big_align = @maximum(big_align, field_align); |
| 878 | const prev_offset = offset; | 882 | const prev_offset = offset; |
| 879 | offset = std.mem.alignForwardGeneric(u64, offset, field_align); | 883 | offset = std.mem.alignForwardGeneric(u64, offset, field_align); |
| 880 | const padding_bytes = @intCast(c_uint, offset - prev_offset); | 884 | const padding_bytes = @intCast(c_uint, offset - prev_offset); |
| ... | @@ -894,6 +898,7 @@ pub const DeclGen = struct { | ... | @@ -894,6 +898,7 @@ pub const DeclGen = struct { |
| 894 | }; | 898 | }; |
| 895 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; | 899 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; |
| 896 | const int_align = int_ty.abiAlignment(target); | 900 | const int_align = int_ty.abiAlignment(target); |
| | 901 | big_align = @maximum(big_align, int_align); |
| 897 | const prev_offset = offset; | 902 | const prev_offset = offset; |
| 898 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); | 903 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); |
| 899 | const padding_bytes = @intCast(c_uint, offset - prev_offset); | 904 | const padding_bytes = @intCast(c_uint, offset - prev_offset); |
| ... | @@ -904,6 +909,14 @@ pub const DeclGen = struct { | ... | @@ -904,6 +909,14 @@ pub const DeclGen = struct { |
| 904 | const llvm_int_ty = try dg.llvmType(int_ty); | 909 | const llvm_int_ty = try dg.llvmType(int_ty); |
| 905 | llvm_field_types.appendAssumeCapacity(llvm_int_ty); | 910 | llvm_field_types.appendAssumeCapacity(llvm_int_ty); |
| 906 | } | 911 | } |
| | 912 | |
| | 913 | const prev_offset = offset; |
| | 914 | offset = std.mem.alignForwardGeneric(u64, offset, big_align); |
| | 915 | const padding_bytes = @intCast(c_uint, offset - prev_offset); |
| | 916 | if (padding_bytes != 0) { |
| | 917 | const padding = dg.context.intType(8).arrayType(padding_bytes); |
| | 918 | llvm_field_types.appendAssumeCapacity(padding); |
| | 919 | } |
| 907 | } else { | 920 | } else { |
| 908 | for (struct_obj.fields.values()) |field| { | 921 | for (struct_obj.fields.values()) |field| { |
| 909 | if (!field.ty.hasCodeGenBits()) continue; | 922 | if (!field.ty.hasCodeGenBits()) continue; |
| ... | @@ -1319,8 +1332,9 @@ pub const DeclGen = struct { | ... | @@ -1319,8 +1332,9 @@ pub const DeclGen = struct { |
| 1319 | const llvm_struct_ty = try dg.llvmType(tv.ty); | 1332 | const llvm_struct_ty = try dg.llvmType(tv.ty); |
| 1320 | const field_vals = tv.val.castTag(.@"struct").?.data; | 1333 | const field_vals = tv.val.castTag(.@"struct").?.data; |
| 1321 | const gpa = dg.gpa; | 1334 | const gpa = dg.gpa; |
| | 1335 | const llvm_field_count = llvm_struct_ty.countStructElementTypes(); |
| 1322 | | 1336 | |
| 1323 | var llvm_fields = try std.ArrayListUnmanaged(*const llvm.Value).initCapacity(gpa, field_vals.len); | 1337 | var llvm_fields = try std.ArrayListUnmanaged(*const llvm.Value).initCapacity(gpa, llvm_field_count); |
| 1324 | defer llvm_fields.deinit(gpa); | 1338 | defer llvm_fields.deinit(gpa); |
| 1325 | | 1339 | |
| 1326 | const struct_obj = tv.ty.castTag(.@"struct").?.data; | 1340 | const struct_obj = tv.ty.castTag(.@"struct").?.data; |
| ... | @@ -1329,6 +1343,7 @@ pub const DeclGen = struct { | ... | @@ -1329,6 +1343,7 @@ pub const DeclGen = struct { |
| 1329 | const fields = struct_obj.fields.values(); | 1343 | const fields = struct_obj.fields.values(); |
| 1330 | comptime assert(Type.packed_struct_layout_version == 1); | 1344 | comptime assert(Type.packed_struct_layout_version == 1); |
| 1331 | var offset: u64 = 0; | 1345 | var offset: u64 = 0; |
| | 1346 | var big_align: u32 = 0; |
| 1332 | var running_bits: u16 = 0; | 1347 | var running_bits: u16 = 0; |
| 1333 | var running_int: *const llvm.Value = llvm_struct_ty.structGetTypeAtIndex(0).constNull(); | 1348 | var running_int: *const llvm.Value = llvm_struct_ty.structGetTypeAtIndex(0).constNull(); |
| 1334 | for (field_vals) |field_val, i| { | 1349 | for (field_vals) |field_val, i| { |
| ... | @@ -1349,6 +1364,7 @@ pub const DeclGen = struct { | ... | @@ -1349,6 +1364,7 @@ pub const DeclGen = struct { |
| 1349 | running_int = running_int.constOr(shifted); | 1364 | running_int = running_int.constOr(shifted); |
| 1350 | running_bits += ty_bit_size; | 1365 | running_bits += ty_bit_size; |
| 1351 | } else { | 1366 | } else { |
| | 1367 | big_align = @maximum(big_align, field_align); |
| 1352 | if (running_bits != 0) { | 1368 | if (running_bits != 0) { |
| 1353 | var int_payload: Type.Payload.Bits = .{ | 1369 | var int_payload: Type.Payload.Bits = .{ |
| 1354 | .base = .{ .tag = .int_unsigned }, | 1370 | .base = .{ .tag = .int_unsigned }, |
| ... | @@ -1356,6 +1372,7 @@ pub const DeclGen = struct { | ... | @@ -1356,6 +1372,7 @@ pub const DeclGen = struct { |
| 1356 | }; | 1372 | }; |
| 1357 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; | 1373 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; |
| 1358 | const int_align = int_ty.abiAlignment(target); | 1374 | const int_align = int_ty.abiAlignment(target); |
| | 1375 | big_align = @maximum(big_align, int_align); |
| 1359 | const prev_offset = offset; | 1376 | const prev_offset = offset; |
| 1360 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); | 1377 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); |
| 1361 | const padding_bytes = @intCast(c_uint, offset - prev_offset); | 1378 | const padding_bytes = @intCast(c_uint, offset - prev_offset); |
| ... | @@ -1382,6 +1399,32 @@ pub const DeclGen = struct { | ... | @@ -1382,6 +1399,32 @@ pub const DeclGen = struct { |
| 1382 | offset += field.ty.abiSize(target); | 1399 | offset += field.ty.abiSize(target); |
| 1383 | } | 1400 | } |
| 1384 | } | 1401 | } |
| | 1402 | if (running_bits != 0) { |
| | 1403 | var int_payload: Type.Payload.Bits = .{ |
| | 1404 | .base = .{ .tag = .int_unsigned }, |
| | 1405 | .data = running_bits, |
| | 1406 | }; |
| | 1407 | const int_ty: Type = .{ .ptr_otherwise = &int_payload.base }; |
| | 1408 | const int_align = int_ty.abiAlignment(target); |
| | 1409 | big_align = @maximum(big_align, int_align); |
| | 1410 | const prev_offset = offset; |
| | 1411 | offset = std.mem.alignForwardGeneric(u64, offset, int_align); |
| | 1412 | const padding_bytes = @intCast(c_uint, offset - prev_offset); |
| | 1413 | if (padding_bytes != 0) { |
| | 1414 | const padding = dg.context.intType(8).arrayType(padding_bytes); |
| | 1415 | llvm_fields.appendAssumeCapacity(padding.getUndef()); |
| | 1416 | } |
| | 1417 | llvm_fields.appendAssumeCapacity(running_int); |
| | 1418 | offset += int_ty.abiSize(target); |
| | 1419 | } |
| | 1420 | |
| | 1421 | const prev_offset = offset; |
| | 1422 | offset = std.mem.alignForwardGeneric(u64, offset, big_align); |
| | 1423 | const padding_bytes = @intCast(c_uint, offset - prev_offset); |
| | 1424 | if (padding_bytes != 0) { |
| | 1425 | const padding = dg.context.intType(8).arrayType(padding_bytes); |
| | 1426 | llvm_fields.appendAssumeCapacity(padding.getUndef()); |
| | 1427 | } |
| 1385 | } else { | 1428 | } else { |
| 1386 | for (field_vals) |field_val, i| { | 1429 | for (field_vals) |field_val, i| { |
| 1387 | const field_ty = tv.ty.structFieldType(i); | 1430 | const field_ty = tv.ty.structFieldType(i); |