| ... | ... | @@ -60,7 +60,7 @@ pub fn classifyWindows(ty: Type, target: Target) Class { |
| 60 | 60 | } |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | | pub const Context = enum { ret, arg }; |
| 63 | pub const Context = enum { ret, arg, other }; |
| 64 | 64 | |
| 65 | 65 | /// There are a maximum of 8 possible return slots. Returned values are in |
| 66 | 66 | /// the beginning of the array; unused slots are filled with .none. |
| ... | ... | @@ -138,7 +138,18 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 138 | 138 | const elem_ty = ty.childType(); |
| 139 | 139 | if (ctx == .arg) { |
| 140 | 140 | const bit_size = ty.bitSize(target); |
| 141 | | if (bit_size > 128) return memory_class; |
| 141 | if (bit_size > 128) { |
| 142 | const has_avx512 = target.cpu.features.isEnabled(@enumToInt(std.Target.x86.Feature.avx512f)); |
| 143 | if (has_avx512 and bit_size <= 512) return .{ |
| 144 | .integer, .integer, .integer, .integer, |
| 145 | .integer, .integer, .integer, .integer, |
| 146 | }; |
| 147 | if (has_avx512 and bit_size <= 256) return .{ |
| 148 | .integer, .integer, .integer, .integer, |
| 149 | .none, .none, .none, .none, |
| 150 | }; |
| 151 | return memory_class; |
| 152 | } |
| 142 | 153 | if (bit_size > 80) return .{ |
| 143 | 154 | .integer, .integer, .none, .none, |
| 144 | 155 | .none, .none, .none, .none, |
| ... | ... | @@ -181,7 +192,8 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 181 | 192 | .sse, .sseup, .sseup, .sseup, |
| 182 | 193 | .sseup, .sseup, .sseup, .none, |
| 183 | 194 | }; |
| 184 | | if (bits <= 512) return .{ |
| 195 | // LLVM always returns vectors byval |
| 196 | if (bits <= 512 or ctx == .ret) return .{ |
| 185 | 197 | .sse, .sseup, .sseup, .sseup, |
| 186 | 198 | .sseup, .sseup, .sseup, .sseup, |
| 187 | 199 | }; |
| ... | ... | @@ -219,7 +231,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 219 | 231 | } |
| 220 | 232 | } |
| 221 | 233 | const field_size = field.ty.abiSize(target); |
| 222 | | const field_class_array = classifySystemV(field.ty, target, .arg); |
| 234 | const field_class_array = classifySystemV(field.ty, target, .other); |
| 223 | 235 | const field_class = std.mem.sliceTo(&field_class_array, .none); |
| 224 | 236 | if (byte_i + field_size <= 8) { |
| 225 | 237 | // Combine this field with the previous one. |
| ... | ... | @@ -333,7 +345,7 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class { |
| 333 | 345 | } |
| 334 | 346 | } |
| 335 | 347 | // Combine this field with the previous one. |
| 336 | | const field_class = classifySystemV(field.ty, target, .arg); |
| 348 | const field_class = classifySystemV(field.ty, target, .other); |
| 337 | 349 | for (result) |*result_item, i| { |
| 338 | 350 | const field_item = field_class[i]; |
| 339 | 351 | // "If both classes are equal, this is the resulting class." |