| ... | @@ -810,8 +810,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u | ... | @@ -810,8 +810,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u |
| 810 | if (abi_align > self.stack_align) | 810 | if (abi_align > self.stack_align) |
| 811 | self.stack_align = abi_align; | 811 | self.stack_align = abi_align; |
| 812 | // TODO find a free slot instead of always appending | 812 | // TODO find a free slot instead of always appending |
| 813 | const offset = mem.alignForwardGeneric(u32, self.next_stack_offset, abi_align); | 813 | const offset = mem.alignForwardGeneric(u32, self.next_stack_offset + abi_size, abi_align); |
| 814 | self.next_stack_offset = offset + abi_size; | 814 | self.next_stack_offset = offset; |
| 815 | if (self.next_stack_offset > self.max_end_stack) | 815 | if (self.next_stack_offset > self.max_end_stack) |
| 816 | self.max_end_stack = self.next_stack_offset; | 816 | self.max_end_stack = self.next_stack_offset; |
| 817 | try self.stack.putNoClobber(self.gpa, offset, .{ | 817 | try self.stack.putNoClobber(self.gpa, offset, .{ |
| ... | @@ -823,7 +823,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u | ... | @@ -823,7 +823,8 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u |
| 823 | | 823 | |
| 824 | /// Use a pointer instruction as the basis for allocating stack memory. | 824 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 825 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | 825 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 826 | const elem_ty = self.air.typeOfIndex(inst).elemType(); | 826 | const ptr_ty = self.air.typeOfIndex(inst); |
| | 827 | const elem_ty = ptr_ty.elemType(); |
| 827 | | 828 | |
| 828 | if (!elem_ty.hasRuntimeBits()) { | 829 | if (!elem_ty.hasRuntimeBits()) { |
| 829 | return self.allocMem(inst, 8, 8); | 830 | return self.allocMem(inst, 8, 8); |
| ... | @@ -833,7 +834,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { | ... | @@ -833,7 +834,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 833 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty}); | 834 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty}); |
| 834 | }; | 835 | }; |
| 835 | // TODO swap this for inst.ty.ptrAlign | 836 | // TODO swap this for inst.ty.ptrAlign |
| 836 | const abi_align = elem_ty.abiAlignment(self.target.*); | 837 | const abi_align = ptr_ty.ptrAlignment(self.target.*); |
| 837 | return self.allocMem(inst, abi_size, abi_align); | 838 | return self.allocMem(inst, abi_size, abi_align); |
| 838 | } | 839 | } |
| 839 | | 840 | |
| ... | @@ -1148,8 +1149,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1148,8 +1149,8 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 1148 | const len_ty = self.air.typeOf(bin_op.rhs); | 1149 | const len_ty = self.air.typeOf(bin_op.rhs); |
| 1149 | | 1150 | |
| 1150 | const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16)); | 1151 | const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16)); |
| 1151 | try self.genSetStack(ptr_ty, stack_offset + 8, ptr); | 1152 | try self.genSetStack(ptr_ty, stack_offset, ptr); |
| 1152 | try self.genSetStack(len_ty, stack_offset, len); | 1153 | try self.genSetStack(len_ty, stack_offset - 8, len); |
| 1153 | const result = MCValue{ .stack_offset = stack_offset }; | 1154 | const result = MCValue{ .stack_offset = stack_offset }; |
| 1154 | | 1155 | |
| 1155 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 1156 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | @@ -1455,7 +1456,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1455,7 +1456,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1455 | const dst_mcv: MCValue = blk: { | 1456 | const dst_mcv: MCValue = blk: { |
| 1456 | switch (operand) { | 1457 | switch (operand) { |
| 1457 | .stack_offset => |off| { | 1458 | .stack_offset => |off| { |
| 1458 | break :blk MCValue{ .stack_offset = off + 8 }; | 1459 | break :blk MCValue{ .stack_offset = off }; |
| 1459 | }, | 1460 | }, |
| 1460 | else => return self.fail("TODO implement slice_ptr for {}", .{operand}), | 1461 | else => return self.fail("TODO implement slice_ptr for {}", .{operand}), |
| 1461 | } | 1462 | } |
| ... | @@ -1472,7 +1473,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1472,7 +1473,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 1472 | const dst_mcv: MCValue = blk: { | 1473 | const dst_mcv: MCValue = blk: { |
| 1473 | switch (operand) { | 1474 | switch (operand) { |
| 1474 | .stack_offset => |off| { | 1475 | .stack_offset => |off| { |
| 1475 | break :blk MCValue{ .stack_offset = off }; | 1476 | break :blk MCValue{ .stack_offset = off - 8 }; |
| 1476 | }, | 1477 | }, |
| 1477 | else => return self.fail("TODO implement slice_len for {}", .{operand}), | 1478 | else => return self.fail("TODO implement slice_len for {}", .{operand}), |
| 1478 | } | 1479 | } |
| ... | @@ -1540,7 +1541,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1540,7 +1541,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1540 | .reg2 = .rbp, | 1541 | .reg2 = .rbp, |
| 1541 | .flags = 0b01, | 1542 | .flags = 0b01, |
| 1542 | }).encode(), | 1543 | }).encode(), |
| 1543 | .data = .{ .imm = @bitCast(u32, -@intCast(i32, off + 16)) }, | 1544 | .data = .{ .imm = @bitCast(u32, -@intCast(i32, off)) }, |
| 1544 | }); | 1545 | }); |
| 1545 | }, | 1546 | }, |
| 1546 | else => return self.fail("TODO implement slice_elem_val when slice is {}", .{slice_mcv}), | 1547 | else => return self.fail("TODO implement slice_elem_val when slice is {}", .{slice_mcv}), |
| ... | @@ -1571,7 +1572,6 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1571,7 +1572,6 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1571 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 1572 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1572 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1573 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1573 | const array_ty = self.air.typeOf(bin_op.lhs); | 1574 | const array_ty = self.air.typeOf(bin_op.lhs); |
| 1574 | const array_abi_size = array_ty.abiSize(self.target.*); | | |
| 1575 | const array = try self.resolveInst(bin_op.lhs); | 1575 | const array = try self.resolveInst(bin_op.lhs); |
| 1576 | array.freezeIfRegister(&self.register_manager); | 1576 | array.freezeIfRegister(&self.register_manager); |
| 1577 | defer array.unfreezeIfRegister(&self.register_manager); | 1577 | defer array.unfreezeIfRegister(&self.register_manager); |
| ... | @@ -1597,7 +1597,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1597,7 +1597,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1597 | .reg1 = addr_reg.to64(), | 1597 | .reg1 = addr_reg.to64(), |
| 1598 | .reg2 = .rbp, | 1598 | .reg2 = .rbp, |
| 1599 | }).encode(), | 1599 | }).encode(), |
| 1600 | .data = .{ .imm = @bitCast(u32, -(off + @intCast(i32, array_abi_size))) }, | 1600 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 1601 | }); | 1601 | }); |
| 1602 | }, | 1602 | }, |
| 1603 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), | 1603 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), |
| ... | @@ -1806,7 +1806,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -1806,7 +1806,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1806 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); | 1806 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 1807 | | 1807 | |
| 1808 | return self.genInlineMemcpy( | 1808 | return self.genInlineMemcpy( |
| 1809 | -(off + @intCast(i32, abi_size)), | 1809 | -off, |
| 1810 | .rbp, | 1810 | .rbp, |
| 1811 | registerAlias(addr_reg, @divExact(reg.size(), 8)), | 1811 | registerAlias(addr_reg, @divExact(reg.size(), 8)), |
| 1812 | count_reg.to64(), | 1812 | count_reg.to64(), |
| ... | @@ -2093,10 +2093,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde | ... | @@ -2093,10 +2093,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 2093 | const mcv = try self.resolveInst(operand); | 2093 | const mcv = try self.resolveInst(operand); |
| 2094 | const ptr_ty = self.air.typeOf(operand); | 2094 | const ptr_ty = self.air.typeOf(operand); |
| 2095 | const struct_ty = ptr_ty.childType(); | 2095 | const struct_ty = ptr_ty.childType(); |
| 2096 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); | | |
| 2097 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); | 2096 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| 2098 | const struct_field_ty = struct_ty.structFieldType(index); | | |
| 2099 | const struct_field_size = @intCast(u32, struct_field_ty.abiSize(self.target.*)); | | |
| 2100 | | 2097 | |
| 2101 | const dst_mcv: MCValue = result: { | 2098 | const dst_mcv: MCValue = result: { |
| 2102 | switch (mcv) { | 2099 | switch (mcv) { |
| ... | @@ -2112,8 +2109,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde | ... | @@ -2112,8 +2109,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 2112 | break :result dst_mcv; | 2109 | break :result dst_mcv; |
| 2113 | }, | 2110 | }, |
| 2114 | .ptr_stack_offset => |off| { | 2111 | .ptr_stack_offset => |off| { |
| 2115 | const offset_to_field = struct_size - struct_field_offset - struct_field_size; | 2112 | const ptr_stack_offset = off - @intCast(i32, struct_field_offset); |
| 2116 | const ptr_stack_offset = off + @intCast(i32, offset_to_field); | | |
| 2117 | break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; | 2113 | break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; |
| 2118 | }, | 2114 | }, |
| 2119 | .register => |reg| { | 2115 | .register => |reg| { |
| ... | @@ -2153,15 +2149,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2153,15 +2149,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2153 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 2149 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2154 | const mcv = try self.resolveInst(operand); | 2150 | const mcv = try self.resolveInst(operand); |
| 2155 | const struct_ty = self.air.typeOf(operand); | 2151 | const struct_ty = self.air.typeOf(operand); |
| 2156 | const struct_size = struct_ty.abiSize(self.target.*); | | |
| 2157 | const struct_field_offset = struct_ty.structFieldOffset(index, self.target.*); | 2152 | const struct_field_offset = struct_ty.structFieldOffset(index, self.target.*); |
| 2158 | const struct_field_ty = struct_ty.structFieldType(index); | 2153 | const struct_field_ty = struct_ty.structFieldType(index); |
| 2159 | const struct_field_size = struct_field_ty.abiSize(self.target.*); | | |
| 2160 | | 2154 | |
| 2161 | switch (mcv) { | 2155 | switch (mcv) { |
| 2162 | .stack_offset => |off| { | 2156 | .stack_offset => |off| { |
| 2163 | const offset_to_field = struct_size - struct_field_offset - struct_field_size; | 2157 | const stack_offset = off - @intCast(i32, struct_field_offset); |
| 2164 | const stack_offset = off + @intCast(i32, offset_to_field); | | |
| 2165 | break :result MCValue{ .stack_offset = stack_offset }; | 2158 | break :result MCValue{ .stack_offset = stack_offset }; |
| 2166 | }, | 2159 | }, |
| 2167 | .register => |reg| { | 2160 | .register => |reg| { |
| ... | @@ -2369,7 +2362,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC | ... | @@ -2369,7 +2362,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 2369 | if (off > math.maxInt(i32)) { | 2362 | if (off > math.maxInt(i32)) { |
| 2370 | return self.fail("stack offset too large", .{}); | 2363 | return self.fail("stack offset too large", .{}); |
| 2371 | } | 2364 | } |
| 2372 | const adj_off = off + @intCast(i32, abi_size); | | |
| 2373 | _ = try self.addInst(.{ | 2365 | _ = try self.addInst(.{ |
| 2374 | .tag = mir_tag, | 2366 | .tag = mir_tag, |
| 2375 | .ops = (Mir.Ops{ | 2367 | .ops = (Mir.Ops{ |
| ... | @@ -2377,7 +2369,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC | ... | @@ -2377,7 +2369,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 2377 | .reg2 = .rbp, | 2369 | .reg2 = .rbp, |
| 2378 | .flags = 0b01, | 2370 | .flags = 0b01, |
| 2379 | }).encode(), | 2371 | }).encode(), |
| 2380 | .data = .{ .imm = @bitCast(u32, -adj_off) }, | 2372 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 2381 | }); | 2373 | }); |
| 2382 | }, | 2374 | }, |
| 2383 | .compare_flags_unsigned => { | 2375 | .compare_flags_unsigned => { |
| ... | @@ -2395,7 +2387,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC | ... | @@ -2395,7 +2387,6 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 2395 | if (abi_size > 8) { | 2387 | if (abi_size > 8) { |
| 2396 | return self.fail("TODO implement ADD/SUB/CMP for stack dst with large ABI", .{}); | 2388 | return self.fail("TODO implement ADD/SUB/CMP for stack dst with large ABI", .{}); |
| 2397 | } | 2389 | } |
| 2398 | const adj_off = off + @intCast(i32, abi_size); | | |
| 2399 | | 2390 | |
| 2400 | switch (src_mcv) { | 2391 | switch (src_mcv) { |
| 2401 | .none => unreachable, | 2392 | .none => unreachable, |
| ... | @@ -2411,7 +2402,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC | ... | @@ -2411,7 +2402,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 2411 | .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)), | 2402 | .reg2 = registerAlias(src_reg, @intCast(u32, abi_size)), |
| 2412 | .flags = 0b10, | 2403 | .flags = 0b10, |
| 2413 | }).encode(), | 2404 | }).encode(), |
| 2414 | .data = .{ .imm = @bitCast(u32, -adj_off) }, | 2405 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 2415 | }); | 2406 | }); |
| 2416 | }, | 2407 | }, |
| 2417 | .immediate => |imm| { | 2408 | .immediate => |imm| { |
| ... | @@ -2432,7 +2423,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC | ... | @@ -2432,7 +2423,7 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 2432 | else => unreachable, | 2423 | else => unreachable, |
| 2433 | }; | 2424 | }; |
| 2434 | const payload = try self.addExtra(Mir.ImmPair{ | 2425 | const payload = try self.addExtra(Mir.ImmPair{ |
| 2435 | .dest_off = @bitCast(u32, -adj_off), | 2426 | .dest_off = @bitCast(u32, -off), |
| 2436 | .operand = @truncate(u32, imm), | 2427 | .operand = @truncate(u32, imm), |
| 2437 | }); | 2428 | }); |
| 2438 | _ = try self.addInst(.{ | 2429 | _ = try self.addInst(.{ |
| ... | @@ -2583,9 +2574,16 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2583,9 +2574,16 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 2583 | self.arg_index += 1; | 2574 | self.arg_index += 1; |
| 2584 | | 2575 | |
| 2585 | const mcv = self.args[arg_index]; | 2576 | const mcv = self.args[arg_index]; |
| | 2577 | const max_stack = loop: for (self.args) |arg| { |
| | 2578 | switch (arg) { |
| | 2579 | .stack_offset => |last| break :loop last, |
| | 2580 | else => {}, |
| | 2581 | } |
| | 2582 | } else 0; |
| 2586 | const payload = try self.addExtra(Mir.ArgDbgInfo{ | 2583 | const payload = try self.addExtra(Mir.ArgDbgInfo{ |
| 2587 | .air_inst = inst, | 2584 | .air_inst = inst, |
| 2588 | .arg_index = arg_index, | 2585 | .arg_index = arg_index, |
| | 2586 | .max_stack = @intCast(u32, max_stack), |
| 2589 | }); | 2587 | }); |
| 2590 | _ = try self.addInst(.{ | 2588 | _ = try self.addInst(.{ |
| 2591 | .tag = .arg_dbg_info, | 2589 | .tag = .arg_dbg_info, |
| ... | @@ -2601,11 +2599,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2601,11 +2599,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 2601 | self.register_manager.getRegAssumeFree(reg.to64(), inst); | 2599 | self.register_manager.getRegAssumeFree(reg.to64(), inst); |
| 2602 | break :blk mcv; | 2600 | break :blk mcv; |
| 2603 | }, | 2601 | }, |
| 2604 | .stack_offset => { | 2602 | .stack_offset => |off| { |
| 2605 | const ty = self.air.typeOfIndex(inst); | 2603 | const offset = max_stack - off + 16; |
| 2606 | const abi_size = ty.abiSize(self.target.*); | 2604 | break :blk MCValue{ .stack_offset = -offset }; |
| 2607 | const off = @intCast(i32, (arg_index + 1) * abi_size) + 16; | | |
| 2608 | break :blk MCValue{ .stack_offset = -off }; | | |
| 2609 | }, | 2605 | }, |
| 2610 | else => return self.fail("TODO implement arg for {}", .{mcv}), | 2606 | else => return self.fail("TODO implement arg for {}", .{mcv}), |
| 2611 | } | 2607 | } |
| ... | @@ -2648,7 +2644,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2648,7 +2644,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2648 | var info = try self.resolveCallingConventionValues(fn_ty); | 2644 | var info = try self.resolveCallingConventionValues(fn_ty); |
| 2649 | defer info.deinit(self); | 2645 | defer info.deinit(self); |
| 2650 | | 2646 | |
| 2651 | var stack_adjustment: u32 = 0; | 2647 | var stack_adjustment: ?u32 = null; |
| 2652 | for (args) |arg, arg_i| { | 2648 | for (args) |arg, arg_i| { |
| 2653 | const mc_arg = info.args[arg_i]; | 2649 | const mc_arg = info.args[arg_i]; |
| 2654 | const arg_ty = self.air.typeOf(arg); | 2650 | const arg_ty = self.air.typeOf(arg); |
| ... | @@ -2662,9 +2658,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2662,9 +2658,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2662 | try self.genSetReg(arg_ty, reg, arg_mcv); | 2658 | try self.genSetReg(arg_ty, reg, arg_mcv); |
| 2663 | }, | 2659 | }, |
| 2664 | .stack_offset => |off| { | 2660 | .stack_offset => |off| { |
| 2665 | const abi_size = @intCast(u32, arg_ty.abiSize(self.target.*)); | | |
| 2666 | try self.genSetStackArg(arg_ty, off, arg_mcv); | 2661 | try self.genSetStackArg(arg_ty, off, arg_mcv); |
| 2667 | stack_adjustment += abi_size; | 2662 | if (stack_adjustment == null) { |
| | 2663 | stack_adjustment = @intCast(u32, off); |
| | 2664 | } |
| 2668 | }, | 2665 | }, |
| 2669 | .ptr_stack_offset => { | 2666 | .ptr_stack_offset => { |
| 2670 | return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); | 2667 | return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{}); |
| ... | @@ -2685,14 +2682,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2685,14 +2682,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2685 | } | 2682 | } |
| 2686 | } | 2683 | } |
| 2687 | | 2684 | |
| 2688 | if (stack_adjustment > 0) { | 2685 | if (stack_adjustment) |off| { |
| 2689 | // Adjust the stack | 2686 | // Adjust the stack |
| 2690 | _ = try self.addInst(.{ | 2687 | _ = try self.addInst(.{ |
| 2691 | .tag = .sub, | 2688 | .tag = .sub, |
| 2692 | .ops = (Mir.Ops{ | 2689 | .ops = (Mir.Ops{ |
| 2693 | .reg1 = .rsp, | 2690 | .reg1 = .rsp, |
| 2694 | }).encode(), | 2691 | }).encode(), |
| 2695 | .data = .{ .imm = stack_adjustment }, | 2692 | .data = .{ .imm = off }, |
| 2696 | }); | 2693 | }); |
| 2697 | } | 2694 | } |
| 2698 | | 2695 | |
| ... | @@ -2820,14 +2817,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2820,14 +2817,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2820 | } | 2817 | } |
| 2821 | } else unreachable; | 2818 | } else unreachable; |
| 2822 | | 2819 | |
| 2823 | if (stack_adjustment > 0) { | 2820 | if (stack_adjustment) |off| { |
| 2824 | // Readjust the stack | 2821 | // Readjust the stack |
| 2825 | _ = try self.addInst(.{ | 2822 | _ = try self.addInst(.{ |
| 2826 | .tag = .add, | 2823 | .tag = .add, |
| 2827 | .ops = (Mir.Ops{ | 2824 | .ops = (Mir.Ops{ |
| 2828 | .reg1 = .rsp, | 2825 | .reg1 = .rsp, |
| 2829 | }).encode(), | 2826 | }).encode(), |
| 2830 | .data = .{ .imm = stack_adjustment }, | 2827 | .data = .{ .imm = off }, |
| 2831 | }); | 2828 | }); |
| 2832 | } | 2829 | } |
| 2833 | | 2830 | |
| ... | @@ -3583,14 +3580,13 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -3583,14 +3580,13 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3583 | return self.genSetStackArg(ty, stack_offset, .{ .register = reg }); | 3580 | return self.genSetStackArg(ty, stack_offset, .{ .register = reg }); |
| 3584 | }, | 3581 | }, |
| 3585 | .immediate => |imm| { | 3582 | .immediate => |imm| { |
| 3586 | const off = stack_offset + @intCast(i32, abi_size); | | |
| 3587 | switch (abi_size) { | 3583 | switch (abi_size) { |
| 3588 | 1, 2, 4 => { | 3584 | 1, 2, 4 => { |
| 3589 | // We have a positive stack offset value but we want a twos complement negative | 3585 | // We have a positive stack offset value but we want a twos complement negative |
| 3590 | // offset from rbp, which is at the top of the stack frame. | 3586 | // offset from rbp, which is at the top of the stack frame. |
| 3591 | // mov [rbp+offset], immediate | 3587 | // mov [rbp+offset], immediate |
| 3592 | const payload = try self.addExtra(Mir.ImmPair{ | 3588 | const payload = try self.addExtra(Mir.ImmPair{ |
| 3593 | .dest_off = @bitCast(u32, -off), | 3589 | .dest_off = @bitCast(u32, -stack_offset), |
| 3594 | .operand = @truncate(u32, imm), | 3590 | .operand = @truncate(u32, imm), |
| 3595 | }); | 3591 | }); |
| 3596 | _ = try self.addInst(.{ | 3592 | _ = try self.addInst(.{ |
| ... | @@ -3680,7 +3676,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -3680,7 +3676,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3680 | // TODO allow for abi_size to be u64 | 3676 | // TODO allow for abi_size to be u64 |
| 3681 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); | 3677 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 3682 | try self.genInlineMemcpy( | 3678 | try self.genInlineMemcpy( |
| 3683 | -(stack_offset + @intCast(i32, abi_size)), | 3679 | -stack_offset, |
| 3684 | .rsp, | 3680 | .rsp, |
| 3685 | addr_reg.to64(), | 3681 | addr_reg.to64(), |
| 3686 | count_reg.to64(), | 3682 | count_reg.to64(), |
| ... | @@ -3695,14 +3691,14 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -3695,14 +3691,14 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3695 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), | 3691 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), |
| 3696 | .flags = 0b10, | 3692 | .flags = 0b10, |
| 3697 | }).encode(), | 3693 | }).encode(), |
| 3698 | .data = .{ .imm = @bitCast(u32, -(stack_offset + @intCast(i32, abi_size))) }, | 3694 | .data = .{ .imm = @bitCast(u32, -stack_offset) }, |
| 3699 | }); | 3695 | }); |
| 3700 | }, | 3696 | }, |
| 3701 | .ptr_stack_offset => { | 3697 | .ptr_stack_offset => { |
| 3702 | const reg = try self.copyToTmpRegister(ty, mcv); | 3698 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 3703 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 3699 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 3704 | }, | 3700 | }, |
| 3705 | .stack_offset => |unadjusted_off| { | 3701 | .stack_offset => |off| { |
| 3706 | if (abi_size <= 8) { | 3702 | if (abi_size <= 8) { |
| 3707 | const reg = try self.copyToTmpRegister(ty, mcv); | 3703 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 3708 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 3704 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| ... | @@ -3725,13 +3721,13 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -3725,13 +3721,13 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3725 | .reg1 = addr_reg.to64(), | 3721 | .reg1 = addr_reg.to64(), |
| 3726 | .reg2 = .rbp, | 3722 | .reg2 = .rbp, |
| 3727 | }).encode(), | 3723 | }).encode(), |
| 3728 | .data = .{ .imm = @bitCast(u32, -(unadjusted_off + @intCast(i32, abi_size))) }, | 3724 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 3729 | }); | 3725 | }); |
| 3730 | | 3726 | |
| 3731 | // TODO allow for abi_size to be u64 | 3727 | // TODO allow for abi_size to be u64 |
| 3732 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); | 3728 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 3733 | try self.genInlineMemcpy( | 3729 | try self.genInlineMemcpy( |
| 3734 | -(stack_offset + @intCast(i32, abi_size)), | 3730 | -stack_offset, |
| 3735 | .rsp, | 3731 | .rsp, |
| 3736 | addr_reg.to64(), | 3732 | addr_reg.to64(), |
| 3737 | count_reg.to64(), | 3733 | count_reg.to64(), |
| ... | @@ -3767,17 +3763,13 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3767,17 +3763,13 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3767 | return self.genSetStack(ty, stack_offset, .{ .register = reg }); | 3763 | return self.genSetStack(ty, stack_offset, .{ .register = reg }); |
| 3768 | }, | 3764 | }, |
| 3769 | .immediate => |x_big| { | 3765 | .immediate => |x_big| { |
| 3770 | const adj_off = stack_offset + @intCast(i32, abi_size); | 3766 | if (stack_offset > 128) { |
| 3771 | if (adj_off > 128) { | | |
| 3772 | return self.fail("TODO implement set stack variable with large stack offset", .{}); | 3767 | return self.fail("TODO implement set stack variable with large stack offset", .{}); |
| 3773 | } | 3768 | } |
| 3774 | switch (abi_size) { | 3769 | switch (abi_size) { |
| 3775 | 1, 2, 4 => { | 3770 | 1, 2, 4 => { |
| 3776 | // We have a positive stack offset value but we want a twos complement negative | | |
| 3777 | // offset from rbp, which is at the top of the stack frame. | | |
| 3778 | // mov [rbp+offset], immediate | | |
| 3779 | const payload = try self.addExtra(Mir.ImmPair{ | 3771 | const payload = try self.addExtra(Mir.ImmPair{ |
| 3780 | .dest_off = @bitCast(u32, -adj_off), | 3772 | .dest_off = @bitCast(u32, -stack_offset), |
| 3781 | .operand = @truncate(u32, x_big), | 3773 | .operand = @truncate(u32, x_big), |
| 3782 | }); | 3774 | }); |
| 3783 | _ = try self.addInst(.{ | 3775 | _ = try self.addInst(.{ |
| ... | @@ -3795,15 +3787,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3795,15 +3787,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3795 | }); | 3787 | }); |
| 3796 | }, | 3788 | }, |
| 3797 | 8 => { | 3789 | 8 => { |
| 3798 | // We have a positive stack offset value but we want a twos complement negative | | |
| 3799 | // offset from rbp, which is at the top of the stack frame. | | |
| 3800 | const negative_offset = -adj_off; | | |
| 3801 | | | |
| 3802 | // 64 bit write to memory would take two mov's anyways so we | 3790 | // 64 bit write to memory would take two mov's anyways so we |
| 3803 | // insted just use two 32 bit writes to avoid register allocation | 3791 | // insted just use two 32 bit writes to avoid register allocation |
| 3804 | { | 3792 | { |
| 3805 | const payload = try self.addExtra(Mir.ImmPair{ | 3793 | const payload = try self.addExtra(Mir.ImmPair{ |
| 3806 | .dest_off = @bitCast(u32, negative_offset + 4), | 3794 | .dest_off = @bitCast(u32, -stack_offset + 4), |
| 3807 | .operand = @truncate(u32, x_big >> 32), | 3795 | .operand = @truncate(u32, x_big >> 32), |
| 3808 | }); | 3796 | }); |
| 3809 | _ = try self.addInst(.{ | 3797 | _ = try self.addInst(.{ |
| ... | @@ -3817,7 +3805,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3817,7 +3805,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3817 | } | 3805 | } |
| 3818 | { | 3806 | { |
| 3819 | const payload = try self.addExtra(Mir.ImmPair{ | 3807 | const payload = try self.addExtra(Mir.ImmPair{ |
| 3820 | .dest_off = @bitCast(u32, negative_offset), | 3808 | .dest_off = @bitCast(u32, -stack_offset), |
| 3821 | .operand = @truncate(u32, x_big), | 3809 | .operand = @truncate(u32, x_big), |
| 3822 | }); | 3810 | }); |
| 3823 | _ = try self.addInst(.{ | 3811 | _ = try self.addInst(.{ |
| ... | @@ -3839,7 +3827,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3839,7 +3827,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3839 | if (stack_offset > math.maxInt(i32)) { | 3827 | if (stack_offset > math.maxInt(i32)) { |
| 3840 | return self.fail("stack offset too large", .{}); | 3828 | return self.fail("stack offset too large", .{}); |
| 3841 | } | 3829 | } |
| 3842 | const adj_off = stack_offset + @intCast(i32, abi_size); | | |
| 3843 | _ = try self.addInst(.{ | 3830 | _ = try self.addInst(.{ |
| 3844 | .tag = .mov, | 3831 | .tag = .mov, |
| 3845 | .ops = (Mir.Ops{ | 3832 | .ops = (Mir.Ops{ |
| ... | @@ -3847,7 +3834,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3847,7 +3834,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3847 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), | 3834 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), |
| 3848 | .flags = 0b10, | 3835 | .flags = 0b10, |
| 3849 | }).encode(), | 3836 | }).encode(), |
| 3850 | .data = .{ .imm = @bitCast(u32, -adj_off) }, | 3837 | .data = .{ .imm = @bitCast(u32, -stack_offset) }, |
| 3851 | }); | 3838 | }); |
| 3852 | }, | 3839 | }, |
| 3853 | .memory, | 3840 | .memory, |
| ... | @@ -3913,7 +3900,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3913,7 +3900,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3913 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); | 3900 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 3914 | | 3901 | |
| 3915 | return self.genInlineMemcpy( | 3902 | return self.genInlineMemcpy( |
| 3916 | -(stack_offset + @intCast(i32, abi_size)), | 3903 | -stack_offset, |
| 3917 | .rbp, | 3904 | .rbp, |
| 3918 | addr_reg.to64(), | 3905 | addr_reg.to64(), |
| 3919 | count_reg.to64(), | 3906 | count_reg.to64(), |
| ... | @@ -3952,14 +3939,14 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3952,14 +3939,14 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3952 | .reg1 = addr_reg.to64(), | 3939 | .reg1 = addr_reg.to64(), |
| 3953 | .reg2 = .rbp, | 3940 | .reg2 = .rbp, |
| 3954 | }).encode(), | 3941 | }).encode(), |
| 3955 | .data = .{ .imm = @bitCast(u32, -(off + @intCast(i32, abi_size))) }, | 3942 | .data = .{ .imm = @bitCast(u32, -off) }, |
| 3956 | }); | 3943 | }); |
| 3957 | | 3944 | |
| 3958 | // TODO allow for abi_size to be u64 | 3945 | // TODO allow for abi_size to be u64 |
| 3959 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); | 3946 | try self.genSetReg(Type.u32, count_reg, .{ .immediate = @intCast(u32, abi_size) }); |
| 3960 | | 3947 | |
| 3961 | return self.genInlineMemcpy( | 3948 | return self.genInlineMemcpy( |
| 3962 | -(stack_offset + @intCast(i32, abi_size)), | 3949 | -stack_offset, |
| 3963 | .rbp, | 3950 | .rbp, |
| 3964 | addr_reg.to64(), | 3951 | addr_reg.to64(), |
| 3965 | count_reg.to64(), | 3952 | count_reg.to64(), |
| ... | @@ -4073,11 +4060,10 @@ fn genInlineMemcpy( | ... | @@ -4073,11 +4060,10 @@ fn genInlineMemcpy( |
| 4073 | fn genInlineMemset(self: *Self, ty: Type, stack_offset: i32, value: MCValue) InnerError!void { | 4060 | fn genInlineMemset(self: *Self, ty: Type, stack_offset: i32, value: MCValue) InnerError!void { |
| 4074 | try self.register_manager.getReg(.rax, null); | 4061 | try self.register_manager.getReg(.rax, null); |
| 4075 | const abi_size = ty.abiSize(self.target.*); | 4062 | const abi_size = ty.abiSize(self.target.*); |
| 4076 | const adj_off = stack_offset + @intCast(i32, abi_size); | 4063 | if (stack_offset > 128) { |
| 4077 | if (adj_off > 128) { | | |
| 4078 | return self.fail("TODO inline memset with large stack offset", .{}); | 4064 | return self.fail("TODO inline memset with large stack offset", .{}); |
| 4079 | } | 4065 | } |
| 4080 | const negative_offset = @bitCast(u32, -adj_off); | 4066 | const negative_offset = @bitCast(u32, -stack_offset); |
| 4081 | | 4067 | |
| 4082 | // We are actually counting `abi_size` bytes; however, we reuse the index register | 4068 | // We are actually counting `abi_size` bytes; however, we reuse the index register |
| 4083 | // as both the counter and offset scaler, hence we need to subtract one from `abi_size` | 4069 | // as both the counter and offset scaler, hence we need to subtract one from `abi_size` |
| ... | @@ -4165,10 +4151,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -4165,10 +4151,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4165 | const abi_size = ty.abiSize(self.target.*); | 4151 | const abi_size = ty.abiSize(self.target.*); |
| 4166 | switch (mcv) { | 4152 | switch (mcv) { |
| 4167 | .dead => unreachable, | 4153 | .dead => unreachable, |
| 4168 | .ptr_stack_offset => |unadjusted_off| { | 4154 | .ptr_stack_offset => |off| { |
| 4169 | const elem_ty = ty.childType(); | | |
| 4170 | const elem_abi_size = elem_ty.abiSize(self.target.*); | | |
| 4171 | const off = unadjusted_off + @intCast(i32, elem_abi_size); | | |
| 4172 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { | 4155 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { |
| 4173 | return self.fail("stack offset too large", .{}); | 4156 | return self.fail("stack offset too large", .{}); |
| 4174 | } | 4157 | } |
| ... | @@ -4391,8 +4374,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -4391,8 +4374,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4391 | } | 4374 | } |
| 4392 | } | 4375 | } |
| 4393 | }, | 4376 | }, |
| 4394 | .stack_offset => |unadjusted_off| { | 4377 | .stack_offset => |off| { |
| 4395 | const off = unadjusted_off + @intCast(i32, abi_size); | | |
| 4396 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { | 4378 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { |
| 4397 | return self.fail("stack offset too large", .{}); | 4379 | return self.fail("stack offset too large", .{}); |
| 4398 | } | 4380 | } |
| ... | @@ -4469,8 +4451,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4469,8 +4451,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 4469 | const array_len = array_ty.arrayLenIncludingSentinel(); | 4451 | const array_len = array_ty.arrayLenIncludingSentinel(); |
| 4470 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: { | 4452 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: { |
| 4471 | const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16)); | 4453 | const stack_offset = @intCast(i32, try self.allocMem(inst, 16, 16)); |
| 4472 | try self.genSetStack(ptr_ty, stack_offset + 8, ptr); | 4454 | try self.genSetStack(ptr_ty, stack_offset, ptr); |
| 4473 | try self.genSetStack(Type.initTag(.u64), stack_offset, .{ .immediate = array_len }); | 4455 | try self.genSetStack(Type.initTag(.u64), stack_offset - 8, .{ .immediate = array_len }); |
| 4474 | break :blk .{ .stack_offset = stack_offset }; | 4456 | break :blk .{ .stack_offset = stack_offset }; |
| 4475 | }; | 4457 | }; |
| 4476 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 4458 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -4883,7 +4865,6 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -4883,7 +4865,6 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 4883 | var next_stack_offset: u32 = 0; | 4865 | var next_stack_offset: u32 = 0; |
| 4884 | var count: usize = param_types.len; | 4866 | var count: usize = param_types.len; |
| 4885 | while (count > 0) : (count -= 1) { | 4867 | while (count > 0) : (count -= 1) { |
| 4886 | // for (param_types) |ty, i| { | | |
| 4887 | const i = count - 1; | 4868 | const i = count - 1; |
| 4888 | const ty = param_types[i]; | 4869 | const ty = param_types[i]; |
| 4889 | if (!ty.hasRuntimeBits()) { | 4870 | if (!ty.hasRuntimeBits()) { |
| ... | @@ -4892,6 +4873,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -4892,6 +4873,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 4892 | continue; | 4873 | continue; |
| 4893 | } | 4874 | } |
| 4894 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); | 4875 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); |
| | 4876 | const param_align = @intCast(u32, ty.abiAlignment(self.target.*)); |
| 4895 | if (by_reg.get(i)) |int_reg| { | 4877 | if (by_reg.get(i)) |int_reg| { |
| 4896 | const aliased_reg = registerAlias(c_abi_int_param_regs[int_reg], param_size); | 4878 | const aliased_reg = registerAlias(c_abi_int_param_regs[int_reg], param_size); |
| 4897 | result.args[i] = .{ .register = aliased_reg }; | 4879 | result.args[i] = .{ .register = aliased_reg }; |
| ... | @@ -4902,8 +4884,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -4902,8 +4884,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 4902 | // such as ptr and len of slices as separate registers. | 4884 | // such as ptr and len of slices as separate registers. |
| 4903 | // TODO: also we need to honor the C ABI for relevant types rather than passing on | 4885 | // TODO: also we need to honor the C ABI for relevant types rather than passing on |
| 4904 | // the stack here. | 4886 | // the stack here. |
| 4905 | result.args[i] = .{ .stack_offset = @intCast(i32, next_stack_offset) }; | 4887 | const offset = mem.alignForwardGeneric(u32, next_stack_offset + param_size, param_align); |
| 4906 | next_stack_offset += param_size; | 4888 | result.args[i] = .{ .stack_offset = @intCast(i32, offset) }; |
| | 4889 | next_stack_offset = offset; |
| 4907 | } | 4890 | } |
| 4908 | } | 4891 | } |
| 4909 | | 4892 | |