@@ -19,8 +19,12 @@ pub fn generate(
19
19
) ! Mir {
20
20
const zcu = pt .zcu ;
21
21
const gpa = zcu .gpa ;
22
+ const ip = & zcu .intern_pool ;
22
23
const func = zcu .funcInfo (func_index );
23
- const func_type = zcu .intern_pool .indexToKey (func .ty ).func_type ;
24
+ const func_zir = func .zir_body_inst .resolveFull (ip ).? ;
25
+ const file = zcu .fileByIndex (func_zir .file );
26
+ const named_params_len = file .zir .? .getParamBody (func_zir .inst ).len ;
27
+ const func_type = ip .indexToKey (func .ty ).func_type ;
24
28
assert (liveness .* == null );
25
29
26
30
const mod = zcu .navFileScope (func .owner_nav ).mod .? ;
@@ -61,35 +65,49 @@ pub fn generate(
61
65
.values = .empty ,
62
66
};
63
67
defer isel .deinit ();
68
+ const is_sysv = ! isel .target .os .tag .isDarwin () and isel .target .os .tag != .windows ;
69
+ const is_sysv_var_args = is_sysv and func_type .is_var_args ;
64
70
65
71
const air_main_body = air .getMainBody ();
66
72
var param_it : Select.CallAbiIterator = .init ;
67
73
const air_args = for (air_main_body , 0.. ) | air_inst_index , body_index | {
68
74
if (air .instructions .items (.tag )[@intFromEnum (air_inst_index )] != .arg ) break air_main_body [0.. body_index ];
69
- const param_ty = air .instructions .items (.data )[@intFromEnum (air_inst_index )].arg .ty .toType ();
70
- const param_vi = try param_it .param (& isel , param_ty );
75
+ const arg = air .instructions .items (.data )[@intFromEnum (air_inst_index )].arg ;
76
+ const param_ty = arg .ty .toType ();
77
+ const param_vi = param_vi : {
78
+ if (arg .zir_param_index >= named_params_len ) {
79
+ assert (func_type .is_var_args );
80
+ if (! is_sysv ) break :param_vi try param_it .nonSysvVarArg (& isel , param_ty );
81
+ }
82
+ break :param_vi try param_it .param (& isel , param_ty );
83
+ };
71
84
tracking_log .debug ("${d} <- %{d}" , .{ @intFromEnum (param_vi .? ), @intFromEnum (air_inst_index ) });
72
85
try isel .live_values .putNoClobber (gpa , air_inst_index , param_vi .? );
73
86
} else unreachable ;
74
87
75
88
const saved_gra_start = if (mod .strip ) param_it .ngrn else Select .CallAbiIterator .ngrn_start ;
76
- const saved_gra_end = if (func_type . is_var_args ) Select .CallAbiIterator .ngrn_end else param_it .ngrn ;
89
+ const saved_gra_end = if (is_sysv_var_args ) Select .CallAbiIterator .ngrn_end else param_it .ngrn ;
77
90
const saved_gra_len = @intFromEnum (saved_gra_end ) - @intFromEnum (saved_gra_start );
78
91
79
92
const saved_vra_start = if (mod .strip ) param_it .nsrn else Select .CallAbiIterator .nsrn_start ;
80
- const saved_vra_end = if (func_type . is_var_args ) Select .CallAbiIterator .nsrn_end else param_it .nsrn ;
93
+ const saved_vra_end = if (is_sysv_var_args ) Select .CallAbiIterator .nsrn_end else param_it .nsrn ;
81
94
const saved_vra_len = @intFromEnum (saved_vra_end ) - @intFromEnum (saved_vra_start );
82
95
83
96
const frame_record = 2 ;
84
97
const named_stack_args : Select.Value.Indirect = .{
85
98
.base = .fp ,
86
99
.offset = 8 * std .mem .alignForward (u7 , frame_record + saved_gra_len , 2 ),
87
100
};
88
- isel .va_list = .{
89
- .__stack = named_stack_args .withOffset (param_it .nsaa ),
90
- .__gr_top = named_stack_args ,
91
- .__vr_top = .{ .base = .fp , .offset = 0 },
92
- };
101
+ const stack_var_args = named_stack_args .withOffset (param_it .nsaa );
102
+ const gr_top = named_stack_args ;
103
+ const vr_top : Select.Value.Indirect = .{ .base = .fp , .offset = 0 };
104
+ isel .va_list = if (is_sysv ) .{ .sysv = .{
105
+ .__stack = stack_var_args ,
106
+ .__gr_top = gr_top ,
107
+ .__vr_top = vr_top ,
108
+ .__gr_offs = @as (i32 , @intFromEnum (Select .CallAbiIterator .ngrn_end ) - @intFromEnum (param_it .ngrn )) * -8 ,
109
+ .__vr_offs = @as (i32 , @intFromEnum (Select .CallAbiIterator .nsrn_end ) - @intFromEnum (param_it .nsrn )) * -16 ,
110
+ } } else .{ .other = stack_var_args };
93
111
94
112
// translate arg locations from caller-based to callee-based
95
113
for (air_args ) | air_inst_index | {
@@ -106,11 +124,9 @@ pub fn generate(
106
124
const first_passed_part_vi = part_it .next ().? ;
107
125
const hint_ra = first_passed_part_vi .hint (& isel ).? ;
108
126
passed_vi .setParent (& isel , .{ .stack_slot = if (hint_ra .isVector ())
109
- isel .va_list .__vr_top .withOffset (@as (i8 , -16 ) *
110
- (@intFromEnum (saved_vra_end ) - @intFromEnum (hint_ra )))
127
+ vr_top .withOffset (@as (i8 , -16 ) * (@intFromEnum (saved_vra_end ) - @intFromEnum (hint_ra )))
111
128
else
112
- isel .va_list .__gr_top .withOffset (@as (i8 , -8 ) *
113
- (@intFromEnum (saved_gra_end ) - @intFromEnum (hint_ra ))) });
129
+ gr_top .withOffset (@as (i8 , -8 ) * (@intFromEnum (saved_gra_end ) - @intFromEnum (hint_ra ))) });
114
130
},
115
131
.stack_slot = > | stack_slot | {
116
132
assert (stack_slot .base == .sp );
@@ -152,13 +168,7 @@ pub fn generate(
152
168
isel .verify (true );
153
169
154
170
const prologue = isel .instructions .items .len ;
155
- const epilogue = try isel .layout (
156
- param_it ,
157
- func_type .is_var_args ,
158
- saved_gra_len ,
159
- saved_vra_len ,
160
- mod ,
161
- );
171
+ const epilogue = try isel .layout (param_it , is_sysv_var_args , saved_gra_len , saved_vra_len , mod );
162
172
163
173
const instructions = try isel .instructions .toOwnedSlice (gpa );
164
174
var mir : Mir = .{
0 commit comments