| 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 | 1808 | // 1. Different machine code instruction when loading into SIMD register. |
| 1809 | 1809 | // 2. The C ABI wants 16 for extern structs. |
| 1810 | 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 | 1812 | .x86_64, |
| 1813 | .riscv64, | |
| 1814 | 1813 | .powerpc64, |
| 1815 | 1814 | .powerpc64le, |
| 1816 | 1815 | .mips64, |
| 1817 | 1816 | .mips64el, |
| 1818 | 1817 | .sparc64, |
| 1819 | => 8, | |
| 1818 | => return switch (target.ofmt) { | |
| 1819 | .c => 16, | |
| 1820 | else => 8, | |
| 1821 | }, | |
| 1820 | 1822 | |
| 1821 | 1823 | // Even LLVMABIAlignmentOfType(i128) agrees on these targets. |
| 1822 | 1824 | .aarch64, |
| 1823 | 1825 | .aarch64_be, |
| 1824 | 1826 | .aarch64_32, |
| 1827 | .riscv64, | |
| 1825 | 1828 | .bpfel, |
| 1826 | 1829 | .bpfeb, |
| 1827 | 1830 | .nvptx, |
src/Module.zig+19-11| ... | ... | @@ -948,20 +948,28 @@ pub const Struct = struct { |
| 948 | 948 | |
| 949 | 949 | switch (layout) { |
| 950 | 950 | .Packed => return 0, |
| 951 | .Auto => return field.ty.abiAlignment(target), | |
| 952 | .Extern => { | |
| 953 | // This logic is duplicated in Type.abiAlignmentAdvanced. | |
| 954 | const ty_abi_align = field.ty.abiAlignment(target); | |
| 955 | ||
| 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); | |
| 951 | .Auto => { | |
| 952 | if (target.ofmt == .c) { | |
| 953 | return alignmentExtern(field, target); | |
| 954 | } else { | |
| 955 | return field.ty.abiAlignment(target); | |
| 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 | 3019 | big_align = @maximum(big_align, field_align); |
| 3020 | 3020 | |
| 3021 | 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 | 3023 | if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) { |
| 3024 | 3024 | // The C ABI requires 128 bit integer fields of structs |
| 3025 | 3025 | // to be 16-bytes aligned. |
| ... | ... | @@ -3348,7 +3348,13 @@ pub const Type = extern union { |
| 3348 | 3348 | .f128 => return AbiSizeAdvanced{ .scalar = 16 }, |
| 3349 | 3349 | |
| 3350 | 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 | 3358 | .x86_64 => return AbiSizeAdvanced{ .scalar = 16 }, |
| 3353 | 3359 | else => { |
| 3354 | 3360 | var payload: Payload.Bits = .{ |
| ... | ... | @@ -4559,6 +4565,12 @@ pub const Type = extern union { |
| 4559 | 4565 | |
| 4560 | 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 | 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 | 100 | .a_align = 8, |
| 101 | 101 | .a_size = 16, |
| 102 | 102 | |
| 103 | .b_align = 8, | |
| 104 | .b_size = 24, | |
| 103 | .b_align = 16, | |
| 104 | .b_size = 32, | |
| 105 | 105 | |
| 106 | 106 | .u128_align = 8, |
| 107 | 107 | .u128_size = 16, |
| ... | ... | @@ -114,8 +114,8 @@ test "alignment and size of structs with 128-bit fields" { |
| 114 | 114 | .a_align = 8, |
| 115 | 115 | .a_size = 16, |
| 116 | 116 | |
| 117 | .b_align = 8, | |
| 118 | .b_size = 24, | |
| 117 | .b_align = 16, | |
| 118 | .b_size = 32, | |
| 119 | 119 | |
| 120 | 120 | .u128_align = 8, |
| 121 | 121 | .u128_size = 16, |
| ... | ... | @@ -126,8 +126,8 @@ test "alignment and size of structs with 128-bit fields" { |
| 126 | 126 | .a_align = 4, |
| 127 | 127 | .a_size = 16, |
| 128 | 128 | |
| 129 | .b_align = 4, | |
| 130 | .b_size = 20, | |
| 129 | .b_align = 16, | |
| 130 | .b_size = 32, | |
| 131 | 131 | |
| 132 | 132 | .u128_align = 4, |
| 133 | 133 | .u128_size = 16, |
| ... | ... | @@ -140,25 +140,39 @@ test "alignment and size of structs with 128-bit fields" { |
| 140 | 140 | .mips64el, |
| 141 | 141 | .powerpc64, |
| 142 | 142 | .powerpc64le, |
| 143 | .riscv64, | |
| 144 | 143 | .sparc64, |
| 145 | 144 | .x86_64, |
| 146 | => .{ | |
| 147 | .a_align = 8, | |
| 148 | .a_size = 16, | |
| 145 | => switch (builtin.object_format) { | |
| 146 | .c => .{ | |
| 147 | .a_align = 16, | |
| 148 | .a_size = 16, | |
| 149 | 149 | |
| 150 | .b_align = 16, | |
| 151 | .b_size = 32, | |
| 150 | .b_align = 16, | |
| 151 | .b_size = 32, | |
| 152 | 152 | |
| 153 | .u128_align = 8, | |
| 154 | .u128_size = 16, | |
| 155 | .u129_align = 8, | |
| 156 | .u129_size = 24, | |
| 153 | .u128_align = 16, | |
| 154 | .u128_size = 16, | |
| 155 | .u129_align = 16, | |
| 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 | 172 | .aarch64, |
| 160 | 173 | .aarch64_be, |
| 161 | 174 | .aarch64_32, |
| 175 | .riscv64, | |
| 162 | 176 | .bpfel, |
| 163 | 177 | .bpfeb, |
| 164 | 178 | .nvptx, |