| ... | @@ -122,19 +122,17 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx: | ... | @@ -122,19 +122,17 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx: |
| 122 | 1, 2, 4, 8 => .integer, | 122 | 1, 2, 4, 8 => .integer, |
| 123 | else => switch (ty.zigTypeTag(zcu)) { | 123 | else => switch (ty.zigTypeTag(zcu)) { |
| 124 | .int => .win_i128, | 124 | .int => .win_i128, |
| 125 | .@"struct", .@"union" => if (ty.containerLayout(zcu) == .@"packed") | 125 | .@"struct", .@"union" => if (ty.containerLayout(zcu) != .@"packed" or |
| 126 | .win_i128 | 126 | target.cpu.has(.x86, .soft_float)) .memory else .win_i128, |
| 127 | else | | |
| 128 | .memory, | | |
| 129 | else => .memory, | 127 | else => .memory, |
| 130 | }, | 128 | }, |
| 131 | }, | 129 | }, |
| 132 | .noreturn => unreachable, | 130 | .noreturn => unreachable, |
| 133 | .float => switch (ty.floatBits(target)) { | 131 | .float => switch (ty.floatBits(target)) { |
| 134 | 16, 32, 64 => .sse, | | |
| 135 | 80 => .memory, | | |
| 136 | 128 => .win_i128, | | |
| 137 | else => unreachable, | 132 | else => unreachable, |
| | 133 | 16, 32, 64 => if (target.cpu.has(.x86, .soft_float)) .integer else .sse, |
| | 134 | 80 => .memory, |
| | 135 | 128 => if (target.cpu.has(.x86, .soft_float)) .memory else .win_i128, |
| 138 | }, | 136 | }, |
| 139 | .vector => { | 137 | .vector => { |
| 140 | const len = ty.vectorLen(zcu); | 138 | const len = ty.vectorLen(zcu); |
| ... | @@ -183,6 +181,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx: | ... | @@ -183,6 +181,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx: |
| 183 | /// the beginning of the array; unused slots are filled with .none. | 181 | /// the beginning of the array; unused slots are filled with .none. |
| 184 | pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class { | 182 | pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class { |
| 185 | switch (ty.zigTypeTag(zcu)) { | 183 | switch (ty.zigTypeTag(zcu)) { |
| | 184 | else => unreachable, |
| 186 | .void => return Class.zero_bit, | 185 | .void => return Class.zero_bit, |
| 187 | .bool => return Class.one_integer, | 186 | .bool => return Class.one_integer, |
| 188 | .noreturn => unreachable, | 187 | .noreturn => unreachable, |
| ... | @@ -195,7 +194,12 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont | ... | @@ -195,7 +194,12 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont |
| 195 | if (bits <= 64 * 4) return Class.four_integers; | 194 | if (bits <= 64 * 4) return Class.four_integers; |
| 196 | return Class.stack; | 195 | return Class.stack; |
| 197 | }, | 196 | }, |
| 198 | .float => switch (ty.floatBits(target)) { | 197 | .float => if (target.cpu.has(.x86, .soft_float)) switch (ty.floatBits(target)) { |
| | 198 | else => unreachable, |
| | 199 | 16, 32, 64 => return Class.one_integer, |
| | 200 | 80, 128 => return Class.two_integers, |
| | 201 | } else switch (ty.floatBits(target)) { |
| | 202 | else => unreachable, |
| 199 | 16 => { | 203 | 16 => { |
| 200 | if (ctx == .other) return Class.stack; | 204 | if (ctx == .other) return Class.stack; |
| 201 | // TODO clang doesn't allow __fp16 as .ret or .arg | 205 | // TODO clang doesn't allow __fp16 as .ret or .arg |
| ... | @@ -203,15 +207,14 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont | ... | @@ -203,15 +207,14 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont |
| 203 | }, | 207 | }, |
| 204 | 32 => return Class.f32, | 208 | 32 => return Class.f32, |
| 205 | 64 => return Class.f64, | 209 | 64 => return Class.f64, |
| 206 | // "Arguments of types __float128, _Decimal128 and __m128 are | | |
| 207 | // split into two halves. The least significant ones belong | | |
| 208 | // to class SSE, the most significant one to class SSEUP." | | |
| 209 | 128 => return Class.f128, | | |
| 210 | // "The 64-bit mantissa of arguments of type long double | 210 | // "The 64-bit mantissa of arguments of type long double |
| 211 | // belongs to class X87, the 16-bit exponent plus 6 bytes | 211 | // belongs to class X87, the 16-bit exponent plus 6 bytes |
| 212 | // of padding belongs to class X87UP." | 212 | // of padding belongs to class X87UP." |
| 213 | 80 => return Class.f80, | 213 | 80 => return Class.f80, |
| 214 | else => unreachable, | 214 | // "Arguments of types __float128, _Decimal128 and __m128 are |
| | 215 | // split into two halves. The least significant ones belong |
| | 216 | // to class SSE, the most significant one to class SSEUP." |
| | 217 | 128 => return Class.f128, |
| 215 | }, | 218 | }, |
| 216 | .pointer => switch (ty.ptrSize(zcu)) { | 219 | .pointer => switch (ty.ptrSize(zcu)) { |
| 217 | .slice => return Class.two_integers, | 220 | .slice => return Class.two_integers, |
| ... | @@ -341,7 +344,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont | ... | @@ -341,7 +344,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont |
| 341 | if (ty_size <= 16) return Class.two_integers; | 344 | if (ty_size <= 16) return Class.two_integers; |
| 342 | return Class.stack; | 345 | return Class.stack; |
| 343 | }, | 346 | }, |
| 344 | else => unreachable, | | |
| 345 | } | 347 | } |
| 346 | } | 348 | } |
| 347 | | 349 | |