authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-04 21:27:26+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-07 22:42:57+02:00
log467d69c68aac0459b6a0c2876083d7295e43134d
treef37571cffb3249012e22566fe53bb8d597e8a784
parent56a131d27a45af793b6adc0795bd240ed74d3634

x86_64: fix SystemV calling convention


1 files changed, 19 insertions(+), 12 deletions(-)

src/arch/x86_64/CodeGen.zig+19-12
......@@ -7216,19 +7216,23 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
72167216 for (param_types) |ty, i| {
72177217 assert(ty.hasRuntimeBits());
72187218
7219 if (self.target.os.tag != .windows) {
7220 return self.fail("TODO SysV calling convention", .{});
7219 const classes: []const abi.Class = switch (self.target.os.tag) {
7220 .windows => &[1]abi.Class{abi.classifyWindows(ty, self.target.*)},
7221 else => mem.sliceTo(&abi.classifySystemV(ty, self.target.*), .none),
7222 };
7223 if (classes.len > 1) {
7224 return self.fail("TODO handle multiple classes per type", .{});
72217225 }
7222
7223 switch (abi.classifyWindows(ty, self.target.*)) {
7226 switch (classes[0]) {
72247227 .integer => blk: {
72257228 if (i >= abi.getCAbiIntParamRegs(self.target.*).len) break :blk; // fallthrough
72267229 result.args[i] = .{ .register = abi.getCAbiIntParamRegs(self.target.*)[i] };
72277230 continue;
72287231 },
7229 .sse => return self.fail("TODO float/vector via SSE on Windows", .{}),
72307232 .memory => {}, // fallthrough
7231 else => unreachable,
7233 else => |class| return self.fail("TODO handle calling convention class {s}", .{
7234 @tagName(class),
7235 }),
72327236 }
72337237
72347238 const param_size = @intCast(u32, ty.abiSize(self.target.*));
......@@ -7237,7 +7241,8 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
72377241 result.args[i] = .{ .stack_offset = @intCast(i32, offset) };
72387242 next_stack_offset = offset;
72397243 }
7240 // Align the stack to 16bytes before allocating shadow stack space.
7244
7245 // Align the stack to 16bytes before allocating shadow stack space (if any).
72417246 const aligned_next_stack_offset = mem.alignForwardGeneric(u32, next_stack_offset, 16);
72427247 const padding = aligned_next_stack_offset - next_stack_offset;
72437248 if (padding > 0) {
......@@ -7247,11 +7252,13 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
72477252 }
72487253 }
72497254
7250 // TODO fix this so that the 16byte alignment padding is at the current value of $rsp, and push
7251 // the args onto the stack so that there is no padding between the first argument and
7252 // the standard preamble.
7253 // alignment padding | ret value (if > 8) | args ... | shadow stack space | $rbp |
7254 result.stack_byte_count = aligned_next_stack_offset + 4 * @sizeOf(u64);
7255 const shadow_stack_space: u32 = switch (self.target.os.tag) {
7256 .windows => @intCast(u32, 4 * @sizeOf(u64)),
7257 else => 0,
7258 };
7259
7260 // alignment padding | args ... | shadow stack space (if any) | ret addr | $rbp |
7261 result.stack_byte_count = aligned_next_stack_offset + shadow_stack_space;
72557262 result.stack_align = 16;
72567263 },
72577264 .Unspecified => {