| ... | ... | @@ -780,6 +780,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 780 | 780 | // TODO Copy registers to the stack |
| 781 | 781 | const mcv = result; |
| 782 | 782 | |
| 783 | try self.genArgDbgInfo(inst, mcv, @intCast(u32, arg_index)); |
| 784 | |
| 783 | 785 | if (self.liveness.isUnused(inst)) |
| 784 | 786 | return self.finishAirBookkeeping(); |
| 785 | 787 | |
| ... | ... | @@ -1038,6 +1040,26 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 1038 | 1040 | |
| 1039 | 1041 | // Common helper functions |
| 1040 | 1042 | |
| 1043 | /// Adds a Type to the .debug_info at the current position. The bytes will be populated later, |
| 1044 | /// after codegen for this symbol is done. |
| 1045 | fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void { |
| 1046 | switch (self.debug_output) { |
| 1047 | .dwarf => |dw| { |
| 1048 | assert(ty.hasRuntimeBits()); |
| 1049 | const dbg_info = &dw.dbg_info; |
| 1050 | const index = dbg_info.items.len; |
| 1051 | try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4 |
| 1052 | const mod = self.bin_file.options.module.?; |
| 1053 | const atom = switch (self.bin_file.tag) { |
| 1054 | .elf => &mod.declPtr(self.mod_fn.owner_decl).link.elf.dbg_info_atom, |
| 1055 | else => unreachable, |
| 1056 | }; |
| 1057 | try dw.addTypeReloc(atom, ty, @intCast(u32, index), null); |
| 1058 | }, |
| 1059 | else => {}, |
| 1060 | } |
| 1061 | } |
| 1062 | |
| 1041 | 1063 | fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { |
| 1042 | 1064 | const gpa = self.gpa; |
| 1043 | 1065 | try self.mir_instructions.ensureUnusedCapacity(gpa, 1); |
| ... | ... | @@ -1166,6 +1188,40 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live |
| 1166 | 1188 | self.finishAirBookkeeping(); |
| 1167 | 1189 | } |
| 1168 | 1190 | |
| 1191 | fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void { |
| 1192 | const ty = self.air.instructions.items(.data)[inst].ty; |
| 1193 | const name = self.mod_fn.getParamName(arg_index); |
| 1194 | const name_with_null = name.ptr[0 .. name.len + 1]; |
| 1195 | |
| 1196 | switch (mcv) { |
| 1197 | .register => |reg| { |
| 1198 | switch (self.debug_output) { |
| 1199 | .dwarf => |dw| { |
| 1200 | const dbg_info = &dw.dbg_info; |
| 1201 | try dbg_info.ensureUnusedCapacity(3); |
| 1202 | dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); |
| 1203 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 1204 | 1, // ULEB128 dwarf expression length |
| 1205 | reg.dwarfLocOp(), |
| 1206 | }); |
| 1207 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 1208 | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 1209 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 1210 | }, |
| 1211 | else => {}, |
| 1212 | } |
| 1213 | }, |
| 1214 | .stack_offset => |offset| { |
| 1215 | _ = offset; |
| 1216 | switch (self.debug_output) { |
| 1217 | .dwarf => {}, |
| 1218 | else => {}, |
| 1219 | } |
| 1220 | }, |
| 1221 | else => {}, |
| 1222 | } |
| 1223 | } |
| 1224 | |
| 1169 | 1225 | fn genLoad(self: *Self, value_reg: Register, addr_reg: Register, comptime off_type: type, off: off_type, abi_size: u64) !void { |
| 1170 | 1226 | assert(off_type == Register or off_type == i13); |
| 1171 | 1227 | |