authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-21 17:43:20+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-22 00:46:35+01:00
log5fb921539b47693f9b28fb414009395e0c7332d5
treeab58b93348a2ab10fc58dc1b7da20adf14786574
parent4a5e75245bc60f76a82bb6bcb70553bec7d7c4f2

stage2: do not copy args passed via stack into functions locals


1 files changed, 108 insertions(+), 154 deletions(-)

src/arch/x86_64/CodeGen.zig+108-154
......@@ -43,7 +43,7 @@ err_msg: ?*ErrorMsg,
4343args: []MCValue,
4444ret_mcv: MCValue,
4545fn_type: Type,
46arg_index: usize,
46arg_index: u32,
4747src_loc: Module.SrcLoc,
4848stack_align: u32,
4949
......@@ -117,9 +117,9 @@ pub const MCValue = union(enum) {
117117 memory: u64,
118118 /// The value is one of the stack variables.
119119 /// If the type is a pointer, it means the pointer address is in the stack at this offset.
120 stack_offset: u32,
120 stack_offset: i32,
121121 /// The value is a pointer to one of the stack variables (payload is stack offset).
122 ptr_stack_offset: u32,
122 ptr_stack_offset: i32,
123123 /// The value is in the compare flags assuming an unsigned operation,
124124 /// with this operator applied on top of it.
125125 compare_flags_unsigned: math.CompareOperator,
......@@ -485,13 +485,12 @@ fn gen(self: *Self) InnerError!void {
485485 });
486486
487487 // Adjust the stack
488 const stack_end = self.max_end_stack;
489 if (stack_end > math.maxInt(i32)) {
488 if (self.max_end_stack > math.maxInt(i32)) {
490489 return self.failSymbol("too much stack used in call parameters", .{});
491490 }
492491 // TODO we should reuse this mechanism to align the stack when calling any function even if
493492 // we do not pass any args on the stack BUT we still push regs to stack with `push` inst.
494 const aligned_stack_end = @intCast(u32, mem.alignForward(stack_end, self.stack_align));
493 const aligned_stack_end = @intCast(u32, mem.alignForward(self.max_end_stack, self.stack_align));
495494 if (aligned_stack_end > 0) {
496495 self.mir_instructions.set(backpatch_stack_sub, .{
497496 .tag = .sub,
......@@ -798,7 +797,7 @@ fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
798797 }
799798 }
800799 const stack_offset = try self.allocMem(inst, abi_size, abi_align);
801 return MCValue{ .stack_offset = stack_offset };
800 return MCValue{ .stack_offset = @intCast(i32, stack_offset) };
802801}
803802
804803pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
......@@ -844,12 +843,12 @@ fn copyToNewRegisterWithExceptions(
844843
845844fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
846845 const stack_offset = try self.allocMemPtr(inst);
847 return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none });
846 return self.finishAir(inst, .{ .ptr_stack_offset = @intCast(i32, stack_offset) }, .{ .none, .none, .none });
848847}
849848
850849fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
851850 const stack_offset = try self.allocMemPtr(inst);
852 return self.finishAir(inst, .{ .ptr_stack_offset = stack_offset }, .{ .none, .none, .none });
851 return self.finishAir(inst, .{ .ptr_stack_offset = @intCast(i32, stack_offset) }, .{ .none, .none, .none });
853852}
854853
855854fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
......@@ -1409,7 +1408,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
14091408 .reg1 = addr_reg.to64(),
14101409 .reg2 = .rbp,
14111410 }).encode(),
1412 .data = .{ .imm = @bitCast(u32, -@intCast(i32, off + array_abi_size)) },
1411 .data = .{ .imm = @bitCast(u32, -(off + @intCast(i32, array_abi_size))) },
14131412 });
14141413 },
14151414 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
......@@ -1613,7 +1612,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
16131612 try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) });
16141613
16151614 return self.genInlineMemcpy(
1616 @bitCast(u32, -@intCast(i32, off + abi_size)),
1615 -(off + @intCast(i32, abi_size)),
16171616 .rbp,
16181617 registerAlias(addr_reg, @divExact(reg.size(), 8)),
16191618 count_reg.to64(),
......@@ -1770,10 +1769,10 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
17701769 return if (self.liveness.isUnused(inst)) .dead else result: {
17711770 const mcv = try self.resolveInst(operand);
17721771 const struct_ty = self.air.typeOf(operand).childType();
1773 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
1774 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
1772 const struct_size = @intCast(i32, struct_ty.abiSize(self.target.*));
1773 const struct_field_offset = @intCast(i32, struct_ty.structFieldOffset(index, self.target.*));
17751774 const struct_field_ty = struct_ty.structFieldType(index);
1776 const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
1775 const struct_field_size = @intCast(i32, struct_field_ty.abiSize(self.target.*));
17771776
17781777 switch (mcv) {
17791778 .ptr_stack_offset => |off| {
......@@ -1793,10 +1792,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
17931792 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
17941793 const mcv = try self.resolveInst(operand);
17951794 const struct_ty = self.air.typeOf(operand);
1796 const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*));
1797 const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
1795 const struct_size = @intCast(i32, struct_ty.abiSize(self.target.*));
1796 const struct_field_offset = @intCast(i32, struct_ty.structFieldOffset(index, self.target.*));
17981797 const struct_field_ty = struct_ty.structFieldType(index);
1799 const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*));
1798 const struct_field_size = @intCast(i32, struct_field_ty.abiSize(self.target.*));
18001799
18011800 switch (mcv) {
18021801 .stack_offset => |off| {
......@@ -1960,7 +1959,7 @@ fn genBinMathOpMir(
19601959 return self.fail("stack offset too large", .{});
19611960 }
19621961 const abi_size = dst_ty.abiSize(self.target.*);
1963 const adj_off = off + abi_size;
1962 const adj_off = off + @intCast(i32, abi_size);
19641963 _ = try self.addInst(.{
19651964 .tag = mir_tag,
19661965 .ops = (Mir.Ops{
......@@ -1968,7 +1967,7 @@ fn genBinMathOpMir(
19681967 .reg2 = .rbp,
19691968 .flags = 0b01,
19701969 }).encode(),
1971 .data = .{ .imm = @bitCast(u32, -@intCast(i32, adj_off)) },
1970 .data = .{ .imm = @bitCast(u32, -adj_off) },
19721971 });
19731972 },
19741973 .compare_flags_unsigned => {
......@@ -1987,7 +1986,7 @@ fn genBinMathOpMir(
19871986 if (abi_size > 8) {
19881987 return self.fail("TODO implement ADD/SUB/CMP for stack dst with large ABI", .{});
19891988 }
1990 const adj_off = off + abi_size;
1989 const adj_off = off + @intCast(i32, abi_size);
19911990
19921991 switch (src_mcv) {
19931992 .none => unreachable,
......@@ -2003,7 +2002,7 @@ fn genBinMathOpMir(
20032002 .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)),
20042003 .flags = 0b10,
20052004 }).encode(),
2006 .data = .{ .imm = @bitCast(u32, -@intCast(i32, adj_off)) },
2005 .data = .{ .imm = @bitCast(u32, -adj_off) },
20072006 });
20082007 },
20092008 .immediate => |imm| {
......@@ -2024,7 +2023,7 @@ fn genBinMathOpMir(
20242023 else => unreachable,
20252024 };
20262025 const payload = try self.addExtra(Mir.ImmPair{
2027 .dest_off = @bitCast(u32, -@intCast(i32, adj_off)),
2026 .dest_off = @bitCast(u32, -adj_off),
20282027 .operand = @truncate(u32, imm),
20292028 });
20302029 _ = try self.addInst(.{
......@@ -2162,7 +2161,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
21622161 const mcv = self.args[arg_index];
21632162 const payload = try self.addExtra(Mir.ArgDbgInfo{
21642163 .air_inst = inst,
2165 .arg_index = @truncate(u32, arg_index), // TODO can arg_index: u32?
2164 .arg_index = arg_index,
21662165 });
21672166 _ = try self.addInst(.{
21682167 .tag = .arg_dbg_info,
......@@ -2178,56 +2177,13 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
21782177 self.register_manager.getRegAssumeFree(reg.to64(), inst);
21792178 break :blk mcv;
21802179 },
2181 .stack_offset => |off| {
2180 .stack_offset => {
21822181 const ty = self.air.typeOfIndex(inst);
21832182 const abi_size = ty.abiSize(self.target.*);
2184
2185 if (abi_size <= 8) {
2186 const reg = try self.register_manager.allocReg(inst, &.{});
2187 _ = try self.addInst(.{
2188 .tag = .mov,
2189 .ops = (Mir.Ops{
2190 .reg1 = registerAlias(reg, @intCast(u32, abi_size)),
2191 .reg2 = .rbp,
2192 .flags = 0b01,
2193 }).encode(),
2194 .data = .{ .imm = off + 16 },
2195 });
2196 break :blk .{ .register = reg };
2197 }
2198
2199 // TODO copy ellision
2200 const dst_mcv = try self.allocRegOrMem(inst, false);
2201 const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx });
2202 const addr_reg = regs[0];
2203 const count_reg = regs[1];
2204 const tmp_reg = regs[2];
2205
2206 try self.register_manager.getReg(.rax, null);
2207 try self.register_manager.getReg(.rcx, null);
2208
2209 _ = try self.addInst(.{
2210 .tag = .lea,
2211 .ops = (Mir.Ops{
2212 .reg1 = addr_reg.to64(),
2213 .reg2 = .rbp,
2214 }).encode(),
2215 .data = .{ .imm = off + 16 },
2216 });
2217
2218 // TODO allow for abi_size to be u64
2219 try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) });
2220 try self.genInlineMemcpy(
2221 @bitCast(u32, -@intCast(i32, dst_mcv.stack_offset + abi_size)),
2222 .rbp,
2223 addr_reg.to64(),
2224 count_reg.to64(),
2225 tmp_reg.to8(),
2226 );
2227
2228 break :blk dst_mcv;
2183 const off = @intCast(i32, (arg_index + 1) * abi_size) + 16;
2184 break :blk MCValue{ .stack_offset = -off };
22292185 },
2230 else => unreachable,
2186 else => return self.fail("TODO implement arg for {}", .{mcv}),
22312187 }
22322188 };
22332189
......@@ -2252,64 +2208,6 @@ fn airFence(self: *Self) !void {
22522208 //return self.finishAirBookkeeping();
22532209}
22542210
2255fn genSetStackArg(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
2256 const abi_size = ty.abiSize(self.target.*);
2257 switch (mcv) {
2258 .dead => unreachable,
2259 .ptr_embedded_in_code => unreachable,
2260 .unreach, .none => return,
2261 .register => |reg| {
2262 _ = try self.addInst(.{
2263 .tag = .mov,
2264 .ops = (Mir.Ops{
2265 .reg1 = .rsp,
2266 .reg2 = registerAlias(reg, @intCast(u32, abi_size)),
2267 .flags = 0b10,
2268 }).encode(),
2269 .data = .{ .imm = @bitCast(u32, -@intCast(i32, stack_offset + abi_size)) },
2270 });
2271 },
2272 .ptr_stack_offset => {
2273 const reg = try self.copyToTmpRegister(ty, mcv);
2274 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
2275 },
2276 .stack_offset => |unadjusted_off| {
2277 if (abi_size <= 8) {
2278 const reg = try self.copyToTmpRegister(ty, mcv);
2279 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
2280 }
2281
2282 const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx });
2283 const addr_reg = regs[0];
2284 const count_reg = regs[1];
2285 const tmp_reg = regs[2];
2286
2287 try self.register_manager.getReg(.rax, null);
2288 try self.register_manager.getReg(.rcx, null);
2289
2290 _ = try self.addInst(.{
2291 .tag = .lea,
2292 .ops = (Mir.Ops{
2293 .reg1 = addr_reg.to64(),
2294 .reg2 = .rbp,
2295 }).encode(),
2296 .data = .{ .imm = @bitCast(u32, -@intCast(i32, unadjusted_off + abi_size)) },
2297 });
2298
2299 // TODO allow for abi_size to be u64
2300 try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) });
2301 try self.genInlineMemcpy(
2302 @bitCast(u32, -@intCast(i32, stack_offset + abi_size)),
2303 .rsp,
2304 addr_reg.to64(),
2305 count_reg.to64(),
2306 tmp_reg.to8(),
2307 );
2308 },
2309 else => return self.fail("TODO implement args on stack for {}", .{mcv}),
2310 }
2311}
2312
23132211fn airCall(self: *Self, inst: Air.Inst.Index) !void {
23142212 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
23152213 const callee = pl_op.operand;
......@@ -2326,12 +2224,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
23262224 var info = try self.resolveCallingConventionValues(fn_ty);
23272225 defer info.deinit(self);
23282226
2329 var count: usize = info.args.len;
23302227 var stack_adjustment: u32 = 0;
2331 while (count > 0) : (count -= 1) {
2332 const arg_i = count - 1;
2228 for (args) |arg, arg_i| {
23332229 const mc_arg = info.args[arg_i];
2334 const arg = args[arg_i];
23352230 const arg_ty = self.air.typeOf(arg);
23362231 const arg_mcv = try self.resolveInst(args[arg_i]);
23372232 // Here we do not use setRegOrMem even though the logic is similar, because
......@@ -2343,9 +2238,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
23432238 try self.genSetReg(arg_ty, reg, arg_mcv);
23442239 },
23452240 .stack_offset => |off| {
2346 const abi_size = arg_ty.abiSize(self.target.*);
2241 const abi_size = @intCast(u32, arg_ty.abiSize(self.target.*));
23472242 try self.genSetStackArg(arg_ty, off, arg_mcv);
2348 stack_adjustment += @intCast(u32, abi_size);
2243 stack_adjustment += abi_size;
23492244 },
23502245 .ptr_stack_offset => {
23512246 return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{});
......@@ -3257,7 +3152,65 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
32573152 }
32583153}
32593154
3260fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
3155fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerError!void {
3156 const abi_size = ty.abiSize(self.target.*);
3157 switch (mcv) {
3158 .dead => unreachable,
3159 .ptr_embedded_in_code => unreachable,
3160 .unreach, .none => return,
3161 .register => |reg| {
3162 _ = try self.addInst(.{
3163 .tag = .mov,
3164 .ops = (Mir.Ops{
3165 .reg1 = .rsp,
3166 .reg2 = registerAlias(reg, @intCast(u32, abi_size)),
3167 .flags = 0b10,
3168 }).encode(),
3169 .data = .{ .imm = @bitCast(u32, -(stack_offset + @intCast(i32, abi_size))) },
3170 });
3171 },
3172 .ptr_stack_offset => {
3173 const reg = try self.copyToTmpRegister(ty, mcv);
3174 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
3175 },
3176 .stack_offset => |unadjusted_off| {
3177 if (abi_size <= 8) {
3178 const reg = try self.copyToTmpRegister(ty, mcv);
3179 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
3180 }
3181
3182 const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx });
3183 const addr_reg = regs[0];
3184 const count_reg = regs[1];
3185 const tmp_reg = regs[2];
3186
3187 try self.register_manager.getReg(.rax, null);
3188 try self.register_manager.getReg(.rcx, null);
3189
3190 _ = try self.addInst(.{
3191 .tag = .lea,
3192 .ops = (Mir.Ops{
3193 .reg1 = addr_reg.to64(),
3194 .reg2 = .rbp,
3195 }).encode(),
3196 .data = .{ .imm = @bitCast(u32, -(unadjusted_off + @intCast(i32, abi_size))) },
3197 });
3198
3199 // TODO allow for abi_size to be u64
3200 try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) });
3201 try self.genInlineMemcpy(
3202 -(stack_offset + @intCast(i32, abi_size)),
3203 .rsp,
3204 addr_reg.to64(),
3205 count_reg.to64(),
3206 tmp_reg.to8(),
3207 );
3208 },
3209 else => return self.fail("TODO implement args on stack for {}", .{mcv}),
3210 }
3211}
3212
3213fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerError!void {
32613214 switch (mcv) {
32623215 .dead => unreachable,
32633216 .ptr_embedded_in_code => unreachable,
......@@ -3284,7 +3237,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
32843237 },
32853238 .immediate => |x_big| {
32863239 const abi_size = ty.abiSize(self.target.*);
3287 const adj_off = stack_offset + abi_size;
3240 const adj_off = stack_offset + @intCast(i32, abi_size);
32883241 if (adj_off > 128) {
32893242 return self.fail("TODO implement set stack variable with large stack offset", .{});
32903243 }
......@@ -3294,7 +3247,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
32943247 // offset from rbp, which is at the top of the stack frame.
32953248 // mov [rbp+offset], immediate
32963249 const payload = try self.addExtra(Mir.ImmPair{
3297 .dest_off = @bitCast(u32, -@intCast(i32, adj_off)),
3250 .dest_off = @bitCast(u32, -adj_off),
32983251 .operand = @truncate(u32, x_big),
32993252 });
33003253 _ = try self.addInst(.{
......@@ -3314,7 +3267,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
33143267 8 => {
33153268 // We have a positive stack offset value but we want a twos complement negative
33163269 // offset from rbp, which is at the top of the stack frame.
3317 const negative_offset = -@intCast(i32, adj_off);
3270 const negative_offset = -adj_off;
33183271
33193272 // 64 bit write to memory would take two mov's anyways so we
33203273 // insted just use two 32 bit writes to avoid register allocation
......@@ -3357,7 +3310,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
33573310 return self.fail("stack offset too large", .{});
33583311 }
33593312 const abi_size = ty.abiSize(self.target.*);
3360 const adj_off = stack_offset + abi_size;
3313 const adj_off = stack_offset + @intCast(i32, abi_size);
33613314 _ = try self.addInst(.{
33623315 .tag = .mov,
33633316 .ops = (Mir.Ops{
......@@ -3365,7 +3318,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
33653318 .reg2 = registerAlias(reg, @intCast(u32, abi_size)),
33663319 .flags = 0b10,
33673320 }).encode(),
3368 .data = .{ .imm = @bitCast(u32, -@intCast(i32, adj_off)) },
3321 .data = .{ .imm = @bitCast(u32, -adj_off) },
33693322 });
33703323 },
33713324 .memory, .embedded_in_code => {
......@@ -3391,7 +3344,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
33913344 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
33923345 }
33933346
3394 const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx });
3347 const regs = try self.register_manager.allocRegs(3, .{ null, null, null }, &.{ .rax, .rcx, .rbp });
33953348 const addr_reg = regs[0];
33963349 const count_reg = regs[1];
33973350 const tmp_reg = regs[2];
......@@ -3405,14 +3358,14 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
34053358 .reg1 = addr_reg.to64(),
34063359 .reg2 = .rbp,
34073360 }).encode(),
3408 .data = .{ .imm = @bitCast(u32, -@intCast(i32, off + abi_size)) },
3361 .data = .{ .imm = @bitCast(u32, -(off + @intCast(i32, abi_size))) },
34093362 });
34103363
34113364 // TODO allow for abi_size to be u64
34123365 try self.genSetReg(Type.initTag(.u32), count_reg, .{ .immediate = @intCast(u32, abi_size) });
34133366
34143367 return self.genInlineMemcpy(
3415 @bitCast(u32, -@intCast(i32, stack_offset + abi_size)),
3368 -(stack_offset + @intCast(i32, abi_size)),
34163369 .rbp,
34173370 addr_reg.to64(),
34183371 count_reg.to64(),
......@@ -3424,7 +3377,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
34243377
34253378fn genInlineMemcpy(
34263379 self: *Self,
3427 stack_offset: u32,
3380 stack_offset: i32,
34283381 stack_reg: Register,
34293382 addr_reg: Register,
34303383 count_reg: Register,
......@@ -3482,7 +3435,7 @@ fn genInlineMemcpy(
34823435 .reg1 = stack_reg,
34833436 .reg2 = tmp_reg.to8(),
34843437 }).encode(),
3485 .data = .{ .imm = stack_offset },
3438 .data = .{ .imm = @bitCast(u32, stack_offset) },
34863439 });
34873440
34883441 // add rcx, 1
......@@ -3523,14 +3476,14 @@ fn genInlineMemcpy(
35233476 try self.performReloc(loop_reloc);
35243477}
35253478
3526fn genInlineMemset(self: *Self, ty: Type, stack_offset: u32, value: MCValue) InnerError!void {
3479fn genInlineMemset(self: *Self, ty: Type, stack_offset: i32, value: MCValue) InnerError!void {
35273480 try self.register_manager.getReg(.rax, null);
35283481 const abi_size = ty.abiSize(self.target.*);
3529 const adj_off = stack_offset + abi_size;
3482 const adj_off = stack_offset + @intCast(i32, abi_size);
35303483 if (adj_off > 128) {
35313484 return self.fail("TODO inline memset with large stack offset", .{});
35323485 }
3533 const negative_offset = @bitCast(u32, -@intCast(i32, adj_off));
3486 const negative_offset = @bitCast(u32, -adj_off);
35343487
35353488 // We are actually counting `abi_size` bytes; however, we reuse the index register
35363489 // as both the counter and offset scaler, hence we need to subtract one from `abi_size`
......@@ -3621,7 +3574,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
36213574 const ptr_abi_size = ty.abiSize(self.target.*);
36223575 const elem_ty = ty.childType();
36233576 const elem_abi_size = elem_ty.abiSize(self.target.*);
3624 const off = unadjusted_off + elem_abi_size;
3577 const off = unadjusted_off + @intCast(i32, elem_abi_size);
36253578 if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) {
36263579 return self.fail("stack offset too large", .{});
36273580 }
......@@ -3631,7 +3584,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
36313584 .reg1 = registerAlias(reg, @intCast(u32, ptr_abi_size)),
36323585 .reg2 = .rbp,
36333586 }).encode(),
3634 .data = .{ .imm = @bitCast(u32, -@intCast(i32, off)) },
3587 .data = .{ .imm = @bitCast(u32, -off) },
36353588 });
36363589 },
36373590 .ptr_embedded_in_code => unreachable,
......@@ -3818,7 +3771,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
38183771 },
38193772 .stack_offset => |unadjusted_off| {
38203773 const abi_size = ty.abiSize(self.target.*);
3821 const off = unadjusted_off + abi_size;
3774 const off = unadjusted_off + @intCast(i32, abi_size);
38223775 if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) {
38233776 return self.fail("stack offset too large", .{});
38243777 }
......@@ -3829,7 +3782,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
38293782 .reg2 = .rbp,
38303783 .flags = 0b01,
38313784 }).encode(),
3832 .data = .{ .imm = @bitCast(u32, -@intCast(i32, off)) },
3785 .data = .{ .imm = @bitCast(u32, -off) },
38333786 });
38343787 },
38353788 }
......@@ -3854,7 +3807,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
38543807 const array_ty = ptr_ty.childType();
38553808 const array_len = array_ty.arrayLenIncludingSentinel();
38563809 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
3857 const stack_offset = try self.allocMem(inst, 16, 16);
3810 const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16));
38583811 try self.genSetStack(ptr_ty, stack_offset + 8, ptr);
38593812 try self.genSetStack(Type.initTag(.u64), stack_offset, .{ .immediate = array_len });
38603813 break :blk .{ .stack_offset = stack_offset };
......@@ -4235,6 +4188,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
42354188 var next_stack_offset: u32 = 0;
42364189 var count: usize = param_types.len;
42374190 while (count > 0) : (count -= 1) {
4191 // for (param_types) |ty, i| {
42384192 const i = count - 1;
42394193 const ty = param_types[i];
42404194 if (!ty.hasCodeGenBits()) {
......@@ -4253,7 +4207,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
42534207 // such as ptr and len of slices as separate registers.
42544208 // TODO: also we need to honor the C ABI for relevant types rather than passing on
42554209 // the stack here.
4256 result.args[i] = .{ .stack_offset = next_stack_offset };
4210 result.args[i] = .{ .stack_offset = @intCast(i32, next_stack_offset) };
42574211 next_stack_offset += param_size;
42584212 }
42594213 }