mirror of
https://github.com/ziglang/zig.git
synced 2025-12-15 18:53:07 +00:00
llvm: correctly handle C ABI structs with f32/f64 alignment differences
Closes #13830
This commit is contained in:
parent
5572c67e73
commit
0013042cbd
@ -5,7 +5,19 @@ const assert = std.debug.assert;
|
|||||||
const Register = @import("bits.zig").Register;
|
const Register = @import("bits.zig").Register;
|
||||||
const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
|
const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
|
||||||
|
|
||||||
pub const Class = enum { integer, sse, sseup, x87, x87up, complex_x87, memory, none, win_i128 };
|
pub const Class = enum {
|
||||||
|
integer,
|
||||||
|
sse,
|
||||||
|
sseup,
|
||||||
|
x87,
|
||||||
|
x87up,
|
||||||
|
complex_x87,
|
||||||
|
memory,
|
||||||
|
none,
|
||||||
|
win_i128,
|
||||||
|
float,
|
||||||
|
float_combine,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn classifyWindows(ty: Type, target: Target) Class {
|
pub fn classifyWindows(ty: Type, target: Target) Class {
|
||||||
// https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
|
// https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
|
||||||
@ -121,7 +133,11 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
32, 64 => {
|
32 => {
|
||||||
|
result[0] = .float;
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
64 => {
|
||||||
result[0] = .sse;
|
result[0] = .sse;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -252,6 +268,9 @@ pub fn classifySystemV(ty: Type, target: Target, ctx: Context) [8]Class {
|
|||||||
combine: {
|
combine: {
|
||||||
// "If both classes are equal, this is the resulting class."
|
// "If both classes are equal, this is the resulting class."
|
||||||
if (result[result_i] == field_class[0]) {
|
if (result[result_i] == field_class[0]) {
|
||||||
|
if (result[result_i] == .float) {
|
||||||
|
result[result_i] = .float_combine;
|
||||||
|
}
|
||||||
break :combine;
|
break :combine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10478,6 +10478,14 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
|
|||||||
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
||||||
llvm_types_index += 1;
|
llvm_types_index += 1;
|
||||||
},
|
},
|
||||||
|
.float => {
|
||||||
|
llvm_types_buffer[llvm_types_index] = dg.context.floatType();
|
||||||
|
llvm_types_index += 1;
|
||||||
|
},
|
||||||
|
.float_combine => {
|
||||||
|
llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
|
||||||
|
llvm_types_index += 1;
|
||||||
|
},
|
||||||
.x87 => {
|
.x87 => {
|
||||||
if (llvm_types_index != 0 or classes[2] != .none) {
|
if (llvm_types_index != 0 or classes[2] != .none) {
|
||||||
return dg.context.voidType();
|
return dg.context.voidType();
|
||||||
@ -10694,6 +10702,14 @@ const ParamTypeIterator = struct {
|
|||||||
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
|
||||||
llvm_types_index += 1;
|
llvm_types_index += 1;
|
||||||
},
|
},
|
||||||
|
.float => {
|
||||||
|
llvm_types_buffer[llvm_types_index] = dg.context.floatType();
|
||||||
|
llvm_types_index += 1;
|
||||||
|
},
|
||||||
|
.float_combine => {
|
||||||
|
llvm_types_buffer[llvm_types_index] = dg.context.floatType().vectorType(2);
|
||||||
|
llvm_types_index += 1;
|
||||||
|
},
|
||||||
.x87 => {
|
.x87 => {
|
||||||
it.zig_index += 1;
|
it.zig_index += 1;
|
||||||
it.llvm_index += 1;
|
it.llvm_index += 1;
|
||||||
|
|||||||
@ -937,7 +937,6 @@ test "CFF: Zig returns to C" {
|
|||||||
try expectOk(c_assert_ret_CFF());
|
try expectOk(c_assert_ret_CFF());
|
||||||
}
|
}
|
||||||
test "CFF: C passes to Zig" {
|
test "CFF: C passes to Zig" {
|
||||||
if (builtin.cpu.arch == .x86_64 and builtin.mode != .Debug) return error.SkipZigTest;
|
|
||||||
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
|
||||||
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
|
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||||
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
|
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||||
@ -948,7 +947,6 @@ test "CFF: C passes to Zig" {
|
|||||||
try expectOk(c_send_CFF());
|
try expectOk(c_send_CFF());
|
||||||
}
|
}
|
||||||
test "CFF: C returns to Zig" {
|
test "CFF: C returns to Zig" {
|
||||||
if (builtin.cpu.arch == .x86_64 and builtin.mode != .Debug) return error.SkipZigTest;
|
|
||||||
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||||
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
|
if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
|
||||||
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
|
if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user