diff options
| author | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2021-04-09 18:02:22 +0200 |
|---|---|---|
| committer | joachimschmidt557 <joachim.schmidt557@outlook.com> | 2021-04-11 10:19:35 +0200 |
| commit | a6ddc12b33d4df48670e7752228b4257933d79c7 (patch) | |
| tree | 4fb3967674127f86afac0850a319839ee0cb62ac /src | |
| parent | c676c21824bd8866a2aea56aa11aeade00595ab0 (diff) | |
| download | zig-a6ddc12b33d4df48670e7752228b4257933d79c7.tar.gz zig-a6ddc12b33d4df48670e7752228b4257933d79c7.zip | |
stage2 codegen: Set MCValue of register arguments to their stack copy
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.zig | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 62bf94101c..c2082fdb4a 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -1681,22 +1681,34 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { switch (mcv) { .register => |reg| { - // Copy arg to stack for better debugging - const ty = inst.base.ty; - const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch { - return self.fail(inst.base.src, "type '{}' too big to fit into stack frame", .{ty}); - }; - const abi_align = ty.abiAlignment(self.target.*); - const stack_offset = try self.allocMem(&inst.base, abi_size, abi_align); - try self.genSetStack(inst.base.src, ty, stack_offset, MCValue{ .register = reg }); - const adjusted_stack_offset = math.negateCast(stack_offset + abi_size) catch { - return self.fail(inst.base.src, "Stack offset too large for arguments", .{}); - }; - + switch (self.debug_output) { + .dwarf => |dbg_out| { + try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3); + dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); + dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT_location, DW.FORM_exprloc + 1, // ULEB128 dwarf expression length + reg.dwarfLocOp(), + }); + try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); + try self.addDbgInfoTypeReloc(inst.base.ty); // DW.AT_type, DW.FORM_ref4 + dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string + }, + .none => {}, + } + }, + .stack_offset => |offset| { switch (self.debug_output) { .dwarf => |dbg_out| { switch (arch) { .arm, .armeb => { + const ty = inst.base.ty; + const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch { + return self.fail(inst.base.src, "type '{}' too big to fit into stack frame", .{ty}); + }; + const adjusted_stack_offset = math.negateCast(offset + abi_size) catch { + return self.fail(inst.base.src, "Stack offset too large for arguments", .{}); + }; + try dbg_out.dbg_info.append(link.File.Elf.abbrev_parameter); // Get length of the LEB128 stack offset @@ -1708,19 +1720,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { try leb128.writeULEB128(dbg_out.dbg_info.writer(), counting_writer.bytes_written + 1); try dbg_out.dbg_info.append(DW.OP_breg11); try leb128.writeILEB128(dbg_out.dbg_info.writer(), adjusted_stack_offset); + + try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); + try self.addDbgInfoTypeReloc(inst.base.ty); // DW.AT_type, DW.FORM_ref4 + dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string }, - else => { - try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3); - dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); - dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT_location, DW.FORM_exprloc - 1, // ULEB128 dwarf expression length - reg.dwarfLocOp(), - }); - }, + else => {}, } - try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); - try self.addDbgInfoTypeReloc(inst.base.ty); // DW.AT_type, DW.FORM_ref4 - dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string }, .none => {}, } @@ -1738,19 +1744,39 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } const result = self.args[arg_index]; - try self.genArgDbgInfo(inst, result); + const mcv = switch (arch) { + // TODO support stack-only registers on all target architectures + .arm, .armeb, .aarch64, .aarch64_32, .aarch64_be => switch (result) { + // Copy registers to the stack + .register => |reg| blk: { + const ty = inst.base.ty; + const abi_size = math.cast(u32, ty.abiSize(self.target.*)) catch { + return self.fail(inst.base.src, "type '{}' too big to fit into stack frame", .{ty}); + }; + const abi_align = ty.abiAlignment(self.target.*); + const stack_offset = try self.allocMem(&inst.base, abi_size, abi_align); + try self.genSetStack(inst.base.src, ty, stack_offset, MCValue{ .register = reg }); + + break :blk MCValue{ .stack_offset = stack_offset }; + }, + else => result, + }, + else => result, + }; + try self.genArgDbgInfo(inst, mcv); if (inst.base.isUnused()) return MCValue.dead; - switch (result) { + switch (mcv) { .register => |reg| { try self.register_manager.registers.ensureCapacity(self.gpa, self.register_manager.registers.count() + 1); self.register_manager.getRegAssumeFree(toCanonicalReg(reg), &inst.base); }, else => {}, } - return result; + + return mcv; } fn genBreakpoint(self: *Self, src: LazySrcLoc) !MCValue { @@ -2257,7 +2283,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { const rhs = try self.resolveInst(inst.rhs); const src_mcv = rhs; - const dst_mcv = if (lhs != .register) try self.copyToNewRegister(&inst.base, lhs) else lhs; + const dst_mcv = if (lhs != .register) try self.copyToNewRegister(inst.lhs, lhs) else lhs; try self.genArmBinOpCode(inst.base.src, dst_mcv.register, dst_mcv, src_mcv, .cmp_eq); const info = inst.lhs.ty.intInfo(self.target.*); |
