authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-31 23:47:17-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-02 04:49:53-04:00
logccefa9dbf5369e0fadc75b9e705e74ec96a02859
treea0e2438ae554fadcaf0a2bc82ee8c86f7bc47e84
parentac68d72d244fafb601725d22631f7834fb14212c

x86_64: implement calling var args functions


1 files changed, 11 insertions(+), 4 deletions(-)

src/arch/x86_64/CodeGen.zig+11-4
...@@ -316,7 +316,7 @@ pub fn generate(...@@ -316,7 +316,7 @@ pub fn generate(
316 defer function.mir_extra.deinit(bin_file.allocator);316 defer function.mir_extra.deinit(bin_file.allocator);
317 defer if (builtin.mode == .Debug) function.mir_to_air_map.deinit();317 defer if (builtin.mode == .Debug) function.mir_to_air_map.deinit();
318318
319 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {319 var call_info = function.resolveCallingConventionValues(fn_type, &.{}) catch |err| switch (err) {
320 error.CodegenFail => return Result{ .fail = function.err_msg.? },320 error.CodegenFail => return Result{ .fail = function.err_msg.? },
321 error.OutOfRegisters => return Result{321 error.OutOfRegisters => return Result{
322 .fail = try ErrorMsg.create(322 .fail = try ErrorMsg.create(
...@@ -5191,7 +5191,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5191,7 +5191,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5191 else => unreachable,5191 else => unreachable,
5192 };5192 };
51935193
5194 var info = try self.resolveCallingConventionValues(fn_ty);5194 var info = try self.resolveCallingConventionValues(fn_ty, args[fn_ty.fnParamLen()..]);
5195 defer info.deinit(self);5195 defer info.deinit(self);
51965196
5197 try self.spillEflagsIfOccupied();5197 try self.spillEflagsIfOccupied();
...@@ -8089,11 +8089,18 @@ const CallMCValues = struct {...@@ -8089,11 +8089,18 @@ const CallMCValues = struct {
8089};8089};
80908090
8091/// Caller must call `CallMCValues.deinit`.8091/// Caller must call `CallMCValues.deinit`.
8092fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {8092fn resolveCallingConventionValues(
8093 self: *Self,
8094 fn_ty: Type,
8095 var_args: []const Air.Inst.Ref,
8096) !CallMCValues {
8093 const cc = fn_ty.fnCallingConvention();8097 const cc = fn_ty.fnCallingConvention();
8094 const param_types = try self.gpa.alloc(Type, fn_ty.fnParamLen());8098 const param_len = fn_ty.fnParamLen();
8099 const param_types = try self.gpa.alloc(Type, param_len + var_args.len);
8095 defer self.gpa.free(param_types);8100 defer self.gpa.free(param_types);
8096 fn_ty.fnParamTypes(param_types);8101 fn_ty.fnParamTypes(param_types);
8102 // TODO: promote var arg types
8103 for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.air.typeOf(arg);
8097 var result: CallMCValues = .{8104 var result: CallMCValues = .{
8098 .args = try self.gpa.alloc(MCValue, param_types.len),8105 .args = try self.gpa.alloc(MCValue, param_types.len),
8099 // These undefined values must be populated before returning from this function.8106 // These undefined values must be populated before returning from this function.