aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-03-31 23:47:17 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2023-04-02 04:49:53 -0400
commitccefa9dbf5369e0fadc75b9e705e74ec96a02859 (patch)
treea0e2438ae554fadcaf0a2bc82ee8c86f7bc47e84 /src
parentac68d72d244fafb601725d22631f7834fb14212c (diff)
downloadzig-ccefa9dbf5369e0fadc75b9e705e74ec96a02859.tar.gz
zig-ccefa9dbf5369e0fadc75b9e705e74ec96a02859.zip
x86_64: implement calling var args functions
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/CodeGen.zig15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index a216ed3c2c..45d8547082 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -316,7 +316,7 @@ pub fn generate(
defer function.mir_extra.deinit(bin_file.allocator);
defer if (builtin.mode == .Debug) function.mir_to_air_map.deinit();
- var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
+ var call_info = function.resolveCallingConventionValues(fn_type, &.{}) catch |err| switch (err) {
error.CodegenFail => return Result{ .fail = function.err_msg.? },
error.OutOfRegisters => return Result{
.fail = try ErrorMsg.create(
@@ -5191,7 +5191,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
else => unreachable,
};
- var info = try self.resolveCallingConventionValues(fn_ty);
+ var info = try self.resolveCallingConventionValues(fn_ty, args[fn_ty.fnParamLen()..]);
defer info.deinit(self);
try self.spillEflagsIfOccupied();
@@ -8089,11 +8089,18 @@ const CallMCValues = struct {
};
/// Caller must call `CallMCValues.deinit`.
-fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
+fn resolveCallingConventionValues(
+ self: *Self,
+ fn_ty: Type,
+ var_args: []const Air.Inst.Ref,
+) !CallMCValues {
const cc = fn_ty.fnCallingConvention();
- const param_types = try self.gpa.alloc(Type, fn_ty.fnParamLen());
+ const param_len = fn_ty.fnParamLen();
+ const param_types = try self.gpa.alloc(Type, param_len + var_args.len);
defer self.gpa.free(param_types);
fn_ty.fnParamTypes(param_types);
+ // TODO: promote var arg types
+ for (param_types[param_len..], var_args) |*param_ty, arg| param_ty.* = self.air.typeOf(arg);
var result: CallMCValues = .{
.args = try self.gpa.alloc(MCValue, param_types.len),
// These undefined values must be populated before returning from this function.