mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 00:26:57 +00:00
x86_64: fix C abi of incomplete sse register
This commit is contained in:
parent
e9efed9ed1
commit
08cecc1c7e
@ -285,17 +285,16 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
|
||||
|
||||
// "If one of the classes is MEMORY, the whole argument is passed in memory"
|
||||
// "If X87UP is not preceded by X87, the whole argument is passed in memory."
|
||||
var found_sseup = false;
|
||||
for (result, 0..) |item, i| switch (item) {
|
||||
for (result, 0..) |class, i| switch (class) {
|
||||
.memory => return memory_class,
|
||||
.x87up => if (i == 0 or result[i - 1] != .x87) return memory_class,
|
||||
.sseup => found_sseup = true,
|
||||
else => continue,
|
||||
};
|
||||
// "If the size of the aggregate exceeds two eightbytes and the first eight-
|
||||
// byte isn’t SSE or any other eightbyte isn’t SSEUP, the whole argument
|
||||
// is passed in memory."
|
||||
if (ty_size > 16 and (result[0] != .sse or !found_sseup)) return memory_class;
|
||||
if (ty_size > 16 and (result[0] != .sse or
|
||||
std.mem.indexOfNone(Class, result[1..], &.{ .sseup, .none }) != null)) return memory_class;
|
||||
|
||||
// "If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE."
|
||||
for (&result, 0..) |*item, i| {
|
||||
|
@ -5478,17 +5478,35 @@ f80_extra_struct c_f80_extra_struct(f80_extra_struct a) {
|
||||
#endif
|
||||
|
||||
#ifndef ZIG_NO_F128
|
||||
__float128 zig_f128(__float128 a);
|
||||
__float128 c_f128(__float128 a) {
|
||||
assert_or_panic((double)a == 12.34);
|
||||
assert_or_panic(zig_f128(12) == 34);
|
||||
return 56.78;
|
||||
}
|
||||
typedef struct {
|
||||
__float128 a;
|
||||
} f128_struct;
|
||||
f128_struct zig_f128_struct(f128_struct a);
|
||||
f128_struct c_f128_struct(f128_struct a) {
|
||||
assert_or_panic((double)a.a == 12.34);
|
||||
f128_struct b = zig_f128_struct((f128_struct){12345});
|
||||
assert_or_panic(b.a == 98765);
|
||||
return (f128_struct){56.78};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
__float128 a, b;
|
||||
} f128_f128_struct;
|
||||
f128_f128_struct zig_f128_f128_struct(f128_f128_struct a);
|
||||
f128_f128_struct c_f128_f128_struct(f128_f128_struct a) {
|
||||
assert_or_panic((double)a.a == 12.34);
|
||||
assert_or_panic((double)a.b == 87.65);
|
||||
f128_f128_struct b = zig_f128_f128_struct((f128_f128_struct){13, 57});
|
||||
assert_or_panic((double)b.a == 24);
|
||||
assert_or_panic((double)b.b == 68);
|
||||
return (f128_f128_struct){56.78, 43.21};
|
||||
}
|
||||
#endif
|
||||
|
||||
void __attribute__((stdcall)) stdcall_scalars(char a, short b, int c, float d, double e) {
|
||||
|
@ -136,7 +136,7 @@ export fn zig_f64(x: f64) void {
|
||||
expect(x == 56.78) catch @panic("test failure: zig_f64");
|
||||
}
|
||||
export fn zig_longdouble(x: c_longdouble) void {
|
||||
if (!builtin.cpu.arch.isWasm()) return; // waiting for #1481
|
||||
if (!builtin.target.isWasm()) return; // waiting for #1481
|
||||
expect(x == 12.34) catch @panic("test failure: zig_longdouble");
|
||||
}
|
||||
|
||||
@ -1671,7 +1671,7 @@ test "bool simd vector" {
|
||||
}
|
||||
|
||||
{
|
||||
if (builtin.target.cpu.arch != .wasm32) c_vector_256_bool(.{
|
||||
if (!builtin.target.isWasm()) c_vector_256_bool(.{
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
@ -2189,7 +2189,7 @@ test "bool simd vector" {
|
||||
try expect(vec[255] == false);
|
||||
}
|
||||
{
|
||||
if (builtin.target.cpu.arch != .wasm32) c_vector_512_bool(.{
|
||||
if (!builtin.target.isWasm()) c_vector_512_bool(.{
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@ -5614,23 +5614,64 @@ test "f80 extra struct" {
|
||||
try expect(a.b == 24);
|
||||
}
|
||||
|
||||
extern fn c_f128(f128) f128;
|
||||
test "f128 bare" {
|
||||
if (!have_f128) return error.SkipZigTest;
|
||||
comptime {
|
||||
skip: {
|
||||
if (builtin.target.isWasm()) break :skip;
|
||||
|
||||
const a = c_f128(12.34);
|
||||
try expect(@as(f64, @floatCast(a)) == 56.78);
|
||||
}
|
||||
_ = struct {
|
||||
export fn zig_f128(x: f128) f128 {
|
||||
expect(x == 12) catch @panic("test failure");
|
||||
return 34;
|
||||
}
|
||||
extern fn c_f128(f128) f128;
|
||||
test "f128 bare" {
|
||||
if (!have_f128) return error.SkipZigTest;
|
||||
|
||||
const f128_struct = extern struct {
|
||||
a: f128,
|
||||
};
|
||||
extern fn c_f128_struct(f128_struct) f128_struct;
|
||||
test "f128 struct" {
|
||||
if (!have_f128) return error.SkipZigTest;
|
||||
const a = c_f128(12.34);
|
||||
try expect(@as(f64, @floatCast(a)) == 56.78);
|
||||
}
|
||||
|
||||
const a = c_f128_struct(.{ .a = 12.34 });
|
||||
try expect(@as(f64, @floatCast(a.a)) == 56.78);
|
||||
const f128_struct = extern struct {
|
||||
a: f128,
|
||||
};
|
||||
export fn zig_f128_struct(a: f128_struct) f128_struct {
|
||||
expect(a.a == 12345) catch @panic("test failure");
|
||||
return .{ .a = 98765 };
|
||||
}
|
||||
extern fn c_f128_struct(f128_struct) f128_struct;
|
||||
test "f128 struct" {
|
||||
if (!have_f128) return error.SkipZigTest;
|
||||
|
||||
const a = c_f128_struct(.{ .a = 12.34 });
|
||||
try expect(@as(f64, @floatCast(a.a)) == 56.78);
|
||||
|
||||
const b = c_f128_f128_struct(.{ .a = 12.34, .b = 87.65 });
|
||||
try expect(@as(f64, @floatCast(b.a)) == 56.78);
|
||||
try expect(@as(f64, @floatCast(b.b)) == 43.21);
|
||||
}
|
||||
|
||||
const f128_f128_struct = extern struct {
|
||||
a: f128,
|
||||
b: f128,
|
||||
};
|
||||
export fn zig_f128_f128_struct(a: f128_f128_struct) f128_f128_struct {
|
||||
expect(a.a == 13) catch @panic("test failure");
|
||||
expect(a.b == 57) catch @panic("test failure");
|
||||
return .{ .a = 24, .b = 68 };
|
||||
}
|
||||
extern fn c_f128_f128_struct(f128_f128_struct) f128_f128_struct;
|
||||
test "f128 f128 struct" {
|
||||
if (!have_f128) return error.SkipZigTest;
|
||||
|
||||
const a = c_f128_struct(.{ .a = 12.34 });
|
||||
try expect(@as(f64, @floatCast(a.a)) == 56.78);
|
||||
|
||||
const b = c_f128_f128_struct(.{ .a = 12.34, .b = 87.65 });
|
||||
try expect(@as(f64, @floatCast(b.a)) == 56.78);
|
||||
try expect(@as(f64, @floatCast(b.b)) == 43.21);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// The stdcall attribute on C functions is ignored when compiled on non-x86
|
||||
|
Loading…
Reference in New Issue
Block a user