aboutsummaryrefslogtreecommitdiff
path: root/src/link/Dwarf.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-10-04 03:42:59 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2023-10-04 14:42:35 -0400
commit2a5335d7b6628115ce29c3c712b55c661181e1d1 (patch)
treed5586d99c167e9da12f02f5fa4a6d82ea5c36e44 /src/link/Dwarf.zig
parent9748096992620a9b1a2169ed3be34616fe417a99 (diff)
downloadzig-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.zig75
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