| ... | ... | @@ -7216,19 +7216,23 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 7216 | 7216 | for (param_types) |ty, i| { |
| 7217 | 7217 | assert(ty.hasRuntimeBits()); |
| 7218 | 7218 | |
| 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", .{}); |
| 7221 | 7225 | } |
| 7222 | | |
| 7223 | | switch (abi.classifyWindows(ty, self.target.*)) { |
| 7226 | switch (classes[0]) { |
| 7224 | 7227 | .integer => blk: { |
| 7225 | 7228 | if (i >= abi.getCAbiIntParamRegs(self.target.*).len) break :blk; // fallthrough |
| 7226 | 7229 | result.args[i] = .{ .register = abi.getCAbiIntParamRegs(self.target.*)[i] }; |
| 7227 | 7230 | continue; |
| 7228 | 7231 | }, |
| 7229 | | .sse => return self.fail("TODO float/vector via SSE on Windows", .{}), |
| 7230 | 7232 | .memory => {}, // fallthrough |
| 7231 | | else => unreachable, |
| 7233 | else => |class| return self.fail("TODO handle calling convention class {s}", .{ |
| 7234 | @tagName(class), |
| 7235 | }), |
| 7232 | 7236 | } |
| 7233 | 7237 | |
| 7234 | 7238 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); |
| ... | ... | @@ -7237,7 +7241,8 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 7237 | 7241 | result.args[i] = .{ .stack_offset = @intCast(i32, offset) }; |
| 7238 | 7242 | next_stack_offset = offset; |
| 7239 | 7243 | } |
| 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). |
| 7241 | 7246 | const aligned_next_stack_offset = mem.alignForwardGeneric(u32, next_stack_offset, 16); |
| 7242 | 7247 | const padding = aligned_next_stack_offset - next_stack_offset; |
| 7243 | 7248 | if (padding > 0) { |
| ... | ... | @@ -7247,11 +7252,13 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 7247 | 7252 | } |
| 7248 | 7253 | } |
| 7249 | 7254 | |
| 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; |
| 7255 | 7262 | result.stack_align = 16; |
| 7256 | 7263 | }, |
| 7257 | 7264 | .Unspecified => { |