diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-10-04 03:42:59 -0400 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-10-04 14:42:35 -0400 |
| commit | 2a5335d7b6628115ce29c3c712b55c661181e1d1 (patch) | |
| tree | d5586d99c167e9da12f02f5fa4a6d82ea5c36e44 /src/link/Dwarf.zig | |
| parent | 9748096992620a9b1a2169ed3be34616fe417a99 (diff) | |
| download | zig-2a5335d7b6628115ce29c3c712b55c661181e1d1.tar.gz zig-2a5335d7b6628115ce29c3c712b55c661181e1d1.zip | |
x86_64: implement C abi for 128-bit integers
Diffstat (limited to 'src/link/Dwarf.zig')
| -rw-r--r-- | src/link/Dwarf.zig | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 2beef48595..cbf5f350e8 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -566,6 +566,7 @@ pub const DeclState = struct { pub const DbgInfoLoc = union(enum) { register: u8, + register_pair: [2]u8, stack: struct { fp_register: u8, offset: i32, @@ -610,6 +611,42 @@ pub const DeclState = struct { leb128.writeULEB128(dbg_info.writer(), reg) catch unreachable; } }, + .register_pair => |regs| { + const reg_bits = self.mod.getTarget().ptrBitWidth(); + const reg_bytes = @as(u8, @intCast(@divExact(reg_bits, 8))); + const abi_size = ty.abiSize(self.mod); + try dbg_info.ensureUnusedCapacity(10); + dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevKind.parameter)); + // DW.AT.location, DW.FORM.exprloc + var expr_len = std.io.countingWriter(std.io.null_writer); + for (regs, 0..) |reg, reg_i| { + if (reg < 32) { + expr_len.writer().writeByte(DW.OP.reg0 + reg) catch unreachable; + } else { + expr_len.writer().writeByte(DW.OP.regx) catch unreachable; + leb128.writeULEB128(expr_len.writer(), reg) catch unreachable; + } + expr_len.writer().writeByte(DW.OP.piece) catch unreachable; + leb128.writeULEB128( + expr_len.writer(), + @min(abi_size - reg_i * reg_bytes, reg_bytes), + ) catch unreachable; + } + leb128.writeULEB128(dbg_info.writer(), expr_len.bytes_written) catch unreachable; + for (regs, 0..) |reg, reg_i| { + if (reg < 32) { + dbg_info.appendAssumeCapacity(DW.OP.reg0 + reg); + } else { + dbg_info.appendAssumeCapacity(DW.OP.regx); + leb128.writeULEB128(dbg_info.writer(), reg) catch unreachable; + } + dbg_info.appendAssumeCapacity(DW.OP.piece); + leb128.writeULEB128( + dbg_info.writer(), + @min(abi_size - reg_i * reg_bytes, reg_bytes), + ) catch unreachable; + } + }, .stack => |info| { try dbg_info.ensureUnusedCapacity(9); dbg_info.appendAssumeCapacity(@intFromEnum(AbbrevKind.parameter)); @@ -676,7 +713,7 @@ pub const DeclState = struct { switch (loc) { .register => |reg| { - try dbg_info.ensureUnusedCapacity(4); + try dbg_info.ensureUnusedCapacity(3); // DW.AT.location, DW.FORM.exprloc var expr_len = std.io.countingWriter(std.io.null_writer); if (reg < 32) { @@ -694,6 +731,42 @@ pub const DeclState = struct { } }, + .register_pair => |regs| { + const reg_bits = self.mod.getTarget().ptrBitWidth(); + const reg_bytes = @as(u8, @intCast(@divExact(reg_bits, 8))); + const abi_size = child_ty.abiSize(self.mod); + try dbg_info.ensureUnusedCapacity(9); + // DW.AT.location, DW.FORM.exprloc + var expr_len = std.io.countingWriter(std.io.null_writer); + for (regs, 0..) |reg, reg_i| { + if (reg < 32) { + expr_len.writer().writeByte(DW.OP.reg0 + reg) catch unreachable; + } else { + expr_len.writer().writeByte(DW.OP.regx) catch unreachable; + leb128.writeULEB128(expr_len.writer(), reg) catch unreachable; + } + expr_len.writer().writeByte(DW.OP.piece) catch unreachable; + leb128.writeULEB128( + expr_len.writer(), + @min(abi_size - reg_i * reg_bytes, reg_bytes), + ) catch unreachable; + } + leb128.writeULEB128(dbg_info.writer(), expr_len.bytes_written) catch unreachable; + for (regs, 0..) |reg, reg_i| { + if (reg < 32) { + dbg_info.appendAssumeCapacity(DW.OP.reg0 + reg); + } else { + dbg_info.appendAssumeCapacity(DW.OP.regx); + leb128.writeULEB128(dbg_info.writer(), reg) catch unreachable; + } + dbg_info.appendAssumeCapacity(DW.OP.piece); + leb128.writeULEB128( + dbg_info.writer(), + @min(abi_size - reg_i * reg_bytes, reg_bytes), + ) catch unreachable; + } + }, + .stack => |info| { try dbg_info.ensureUnusedCapacity(9); // DW.AT.location, DW.FORM.exprloc |
