| author | |
| committer | |
| log | cee82c7ce4fb8beb39042f9dba16a1a391803fa4 |
| tree | ea2a12b10b3742acc3f343a36bf14a8c34246776 |
| parent | b975f7a56fec9e0e7aca9832282bc772c743d731 |
* riscv64: adjust alignment and size of 128-bit integers.
* take ofmt=c into account for ABI alignment of 128-bit integers and
structs.
* Type: make packed struct support intInfo
* fix f80 alignment for i386-windows-msvc4 files changed, 69 insertions(+), 32 deletions(-)
lib/std/target.zig+6-3| ... | @@ -1808,20 +1808,23 @@ pub const Target = struct { | ... | @@ -1808,20 +1808,23 @@ pub const Target = struct { |
| 1808 | // 1. Different machine code instruction when loading into SIMD register. | 1808 | // 1. Different machine code instruction when loading into SIMD register. |
| 1809 | // 2. The C ABI wants 16 for extern structs. | 1809 | // 2. The C ABI wants 16 for extern structs. |
| 1810 | // 3. 16-byte cmpxchg needs 16-byte alignment. | 1810 | // 3. 16-byte cmpxchg needs 16-byte alignment. |
| 1811 | // Same logic for riscv64, powerpc64, mips64, sparc64. | 1811 | // Same logic for powerpc64, mips64, sparc64. |
| 1812 | .x86_64, | 1812 | .x86_64, |
| 1813 | .riscv64, | ||
| 1814 | .powerpc64, | 1813 | .powerpc64, |
| 1815 | .powerpc64le, | 1814 | .powerpc64le, |
| 1816 | .mips64, | 1815 | .mips64, |
| 1817 | .mips64el, | 1816 | .mips64el, |
| 1818 | .sparc64, | 1817 | .sparc64, |
| 1819 | => 8, | 1818 | => return switch (target.ofmt) { |
| 1819 | .c => 16, | ||
| 1820 | else => 8, | ||
| 1821 | }, | ||
| 1820 | 1822 | ||
| 1821 | // Even LLVMABIAlignmentOfType(i128) agrees on these targets. | 1823 | // Even LLVMABIAlignmentOfType(i128) agrees on these targets. |
| 1822 | .aarch64, | 1824 | .aarch64, |
| 1823 | .aarch64_be, | 1825 | .aarch64_be, |
| 1824 | .aarch64_32, | 1826 | .aarch64_32, |
| 1827 | .riscv64, | ||
| 1825 | .bpfel, | 1828 | .bpfel, |
| 1826 | .bpfeb, | 1829 | .bpfeb, |
| 1827 | .nvptx, | 1830 | .nvptx, |
src/Module.zig+19-11| ... | @@ -948,20 +948,28 @@ pub const Struct = struct { | ... | @@ -948,20 +948,28 @@ pub const Struct = struct { |
| 948 | 948 | ||
| 949 | switch (layout) { | 949 | switch (layout) { |
| 950 | .Packed => return 0, | 950 | .Packed => return 0, |
| 951 | .Auto => return field.ty.abiAlignment(target), | 951 | .Auto => { |
| 952 | .Extern => { | 952 | if (target.ofmt == .c) { |
| 953 | // This logic is duplicated in Type.abiAlignmentAdvanced. | 953 | return alignmentExtern(field, target); |
| 954 | const ty_abi_align = field.ty.abiAlignment(target); | 954 | } else { |
| 955 | 955 | return field.ty.abiAlignment(target); | |
| 956 | if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) { | ||
| 957 | // The C ABI requires 128 bit integer fields of structs | ||
| 958 | // to be 16-bytes aligned. | ||
| 959 | return @maximum(ty_abi_align, 16); | ||
| 960 | } | 956 | } |
| 961 | |||
| 962 | return ty_abi_align; | ||
| 963 | }, | 957 | }, |
| 958 | .Extern => return alignmentExtern(field, target), | ||
| 959 | } | ||
| 960 | } | ||
| 961 | |||
| 962 | pub fn alignmentExtern(field: Field, target: Target) u32 { | ||
| 963 | // This logic is duplicated in Type.abiAlignmentAdvanced. | ||
| 964 | const ty_abi_align = field.ty.abiAlignment(target); | ||
| 965 | |||
| 966 | if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) { | ||
| 967 | // The C ABI requires 128 bit integer fields of structs | ||
| 968 | // to be 16-bytes aligned. | ||
| 969 | return @maximum(ty_abi_align, 16); | ||
| 964 | } | 970 | } |
| 971 | |||
| 972 | return ty_abi_align; | ||
| 965 | } | 973 | } |
| 966 | }; | 974 | }; |
| 967 | 975 |
src/type.zig+14-2| ... | @@ -3019,7 +3019,7 @@ pub const Type = extern union { | ... | @@ -3019,7 +3019,7 @@ pub const Type = extern union { |
| 3019 | big_align = @maximum(big_align, field_align); | 3019 | big_align = @maximum(big_align, field_align); |
| 3020 | 3020 | ||
| 3021 | // This logic is duplicated in Module.Struct.Field.alignment. | 3021 | // This logic is duplicated in Module.Struct.Field.alignment. |
| 3022 | if (struct_obj.layout == .Extern) { | 3022 | if (struct_obj.layout == .Extern or target.ofmt == .c) { |
| 3023 | if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) { | 3023 | if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) { |
| 3024 | // The C ABI requires 128 bit integer fields of structs | 3024 | // The C ABI requires 128 bit integer fields of structs |
| 3025 | // to be 16-bytes aligned. | 3025 | // to be 16-bytes aligned. |
| ... | @@ -3348,7 +3348,13 @@ pub const Type = extern union { | ... | @@ -3348,7 +3348,13 @@ pub const Type = extern union { |
| 3348 | .f128 => return AbiSizeAdvanced{ .scalar = 16 }, | 3348 | .f128 => return AbiSizeAdvanced{ .scalar = 16 }, |
| 3349 | 3349 | ||
| 3350 | .f80 => switch (target.cpu.arch) { | 3350 | .f80 => switch (target.cpu.arch) { |
| 3351 | .i386 => return AbiSizeAdvanced{ .scalar = 12 }, | 3351 | .i386 => switch (target.os.tag) { |
| 3352 | .windows => switch (target.abi) { | ||
| 3353 | .msvc => return AbiSizeAdvanced{ .scalar = 16 }, | ||
| 3354 | else => return AbiSizeAdvanced{ .scalar = 12 }, | ||
| 3355 | }, | ||
| 3356 | else => return AbiSizeAdvanced{ .scalar = 12 }, | ||
| 3357 | }, | ||
| 3352 | .x86_64 => return AbiSizeAdvanced{ .scalar = 16 }, | 3358 | .x86_64 => return AbiSizeAdvanced{ .scalar = 16 }, |
| 3353 | else => { | 3359 | else => { |
| 3354 | var payload: Payload.Bits = .{ | 3360 | var payload: Payload.Bits = .{ |
| ... | @@ -4559,6 +4565,12 @@ pub const Type = extern union { | ... | @@ -4559,6 +4565,12 @@ pub const Type = extern union { |
| 4559 | 4565 | ||
| 4560 | .vector => ty = ty.castTag(.vector).?.data.elem_type, | 4566 | .vector => ty = ty.castTag(.vector).?.data.elem_type, |
| 4561 | 4567 | ||
| 4568 | .@"struct" => { | ||
| 4569 | const struct_obj = ty.castTag(.@"struct").?.data; | ||
| 4570 | assert(struct_obj.layout == .Packed); | ||
| 4571 | ty = struct_obj.backing_int_ty; | ||
| 4572 | }, | ||
| 4573 | |||
| 4562 | else => unreachable, | 4574 | else => unreachable, |
| 4563 | }; | 4575 | }; |
| 4564 | } | 4576 | } |
test/behavior/align.zig+30-16| ... | @@ -100,8 +100,8 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -100,8 +100,8 @@ test "alignment and size of structs with 128-bit fields" { |
| 100 | .a_align = 8, | 100 | .a_align = 8, |
| 101 | .a_size = 16, | 101 | .a_size = 16, |
| 102 | 102 | ||
| 103 | .b_align = 8, | 103 | .b_align = 16, |
| 104 | .b_size = 24, | 104 | .b_size = 32, |
| 105 | 105 | ||
| 106 | .u128_align = 8, | 106 | .u128_align = 8, |
| 107 | .u128_size = 16, | 107 | .u128_size = 16, |
| ... | @@ -114,8 +114,8 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -114,8 +114,8 @@ test "alignment and size of structs with 128-bit fields" { |
| 114 | .a_align = 8, | 114 | .a_align = 8, |
| 115 | .a_size = 16, | 115 | .a_size = 16, |
| 116 | 116 | ||
| 117 | .b_align = 8, | 117 | .b_align = 16, |
| 118 | .b_size = 24, | 118 | .b_size = 32, |
| 119 | 119 | ||
| 120 | .u128_align = 8, | 120 | .u128_align = 8, |
| 121 | .u128_size = 16, | 121 | .u128_size = 16, |
| ... | @@ -126,8 +126,8 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -126,8 +126,8 @@ test "alignment and size of structs with 128-bit fields" { |
| 126 | .a_align = 4, | 126 | .a_align = 4, |
| 127 | .a_size = 16, | 127 | .a_size = 16, |
| 128 | 128 | ||
| 129 | .b_align = 4, | 129 | .b_align = 16, |
| 130 | .b_size = 20, | 130 | .b_size = 32, |
| 131 | 131 | ||
| 132 | .u128_align = 4, | 132 | .u128_align = 4, |
| 133 | .u128_size = 16, | 133 | .u128_size = 16, |
| ... | @@ -140,25 +140,39 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -140,25 +140,39 @@ test "alignment and size of structs with 128-bit fields" { |
| 140 | .mips64el, | 140 | .mips64el, |
| 141 | .powerpc64, | 141 | .powerpc64, |
| 142 | .powerpc64le, | 142 | .powerpc64le, |
| 143 | .riscv64, | ||
| 144 | .sparc64, | 143 | .sparc64, |
| 145 | .x86_64, | 144 | .x86_64, |
| 146 | => .{ | 145 | => switch (builtin.object_format) { |
| 147 | .a_align = 8, | 146 | .c => .{ |
| 148 | .a_size = 16, | 147 | .a_align = 16, |
| 148 | .a_size = 16, | ||
| 149 | 149 | ||
| 150 | .b_align = 16, | 150 | .b_align = 16, |
| 151 | .b_size = 32, | 151 | .b_size = 32, |
| 152 | 152 | ||
| 153 | .u128_align = 8, | 153 | .u128_align = 16, |
| 154 | .u128_size = 16, | 154 | .u128_size = 16, |
| 155 | .u129_align = 8, | 155 | .u129_align = 16, |
| 156 | .u129_size = 24, | 156 | .u129_size = 32, |
| 157 | }, | ||
| 158 | else => .{ | ||
| 159 | .a_align = 8, | ||
| 160 | .a_size = 16, | ||
| 161 | |||
| 162 | .b_align = 16, | ||
| 163 | .b_size = 32, | ||
| 164 | |||
| 165 | .u128_align = 8, | ||
| 166 | .u128_size = 16, | ||
| 167 | .u129_align = 8, | ||
| 168 | .u129_size = 24, | ||
| 169 | }, | ||
| 157 | }, | 170 | }, |
| 158 | 171 | ||
| 159 | .aarch64, | 172 | .aarch64, |
| 160 | .aarch64_be, | 173 | .aarch64_be, |
| 161 | .aarch64_32, | 174 | .aarch64_32, |
| 175 | .riscv64, | ||
| 162 | .bpfel, | 176 | .bpfel, |
| 163 | .bpfeb, | 177 | .bpfeb, |
| 164 | .nvptx, | 178 | .nvptx, |