mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
codegen: implement lowering aligned anon decls
This commit is contained in:
parent
dd402f6d83
commit
c4fcf0e22a
@ -3153,11 +3153,8 @@ fn lowerAnonDeclRef(
|
||||
return WValue{ .imm32 = 0xaaaaaaaa };
|
||||
}
|
||||
|
||||
const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
|
||||
if (alignment != .none) {
|
||||
@panic("TODO how to make this anon decl be aligned?");
|
||||
}
|
||||
const res = try func.bin_file.lowerAnonDecl(decl_val, func.decl.srcLoc(mod));
|
||||
const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
|
||||
const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.srcLoc(mod));
|
||||
switch (res) {
|
||||
.ok => {},
|
||||
.fail => |em| {
|
||||
|
||||
@ -731,16 +731,13 @@ fn lowerAnonDeclRef(
|
||||
return Result.ok;
|
||||
}
|
||||
|
||||
const res = try bin_file.lowerAnonDecl(decl_val, src_loc);
|
||||
const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
|
||||
const res = try bin_file.lowerAnonDecl(decl_val, decl_align, src_loc);
|
||||
switch (res) {
|
||||
.ok => {},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
|
||||
const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
|
||||
if (alignment != .none) {
|
||||
@panic("TODO how to make this anon decl be aligned?");
|
||||
}
|
||||
const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{
|
||||
.parent_atom_index = reloc_info.parent_atom_index,
|
||||
.offset = code.items.len,
|
||||
|
||||
10
src/link.zig
10
src/link.zig
@ -940,15 +940,15 @@ pub const File = struct {
|
||||
|
||||
pub const LowerResult = @import("codegen.zig").Result;
|
||||
|
||||
pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !LowerResult {
|
||||
pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult {
|
||||
if (build_options.only_c) unreachable;
|
||||
switch (base.tag) {
|
||||
.coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, src_loc),
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, src_loc),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, src_loc),
|
||||
.coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
|
||||
.plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc),
|
||||
.c => unreachable,
|
||||
.wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, src_loc),
|
||||
.wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
|
||||
.spirv => unreachable,
|
||||
.nvptx => unreachable,
|
||||
}
|
||||
|
||||
@ -1091,7 +1091,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
|
||||
const index = unnamed_consts.items.len;
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
|
||||
defer gpa.free(sym_name);
|
||||
const atom_index = switch (try self.lowerConst(sym_name, tv, self.rdata_section_index.?, decl.srcLoc(mod))) {
|
||||
const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) {
|
||||
.ok => |atom_index| atom_index,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
@ -1109,13 +1109,12 @@ const LowerConstResult = union(enum) {
|
||||
fail: *Module.ErrorMsg,
|
||||
};
|
||||
|
||||
fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
|
||||
fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const mod = self.base.options.module.?;
|
||||
const atom_index = try self.createAtom();
|
||||
const sym = self.getAtom(atom_index).getSymbolPtr(self);
|
||||
try self.setSymbolName(sym, name);
|
||||
@ -1129,10 +1128,13 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_l
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
|
||||
const required_alignment: u32 = @intCast(tv.ty.abiAlignment(mod).toByteUnits(0));
|
||||
const atom = self.getAtomPtr(atom_index);
|
||||
atom.size = @as(u32, @intCast(code.len));
|
||||
atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment);
|
||||
atom.getSymbolPtr(self).value = try self.allocateAtom(
|
||||
atom_index,
|
||||
atom.size,
|
||||
@intCast(required_alignment.toByteUnitsOptional().?),
|
||||
);
|
||||
errdefer self.freeAtom(atom_index);
|
||||
|
||||
log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(self).value });
|
||||
@ -1736,7 +1738,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
// This is basically the same as lowerUnnamedConst.
|
||||
// example:
|
||||
// const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
@ -1747,15 +1749,21 @@ pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.Sr
|
||||
// to put it in some location.
|
||||
// ...
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
if (!gop.found_existing) {
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const required_alignment = switch (decl_align) {
|
||||
.none => ty.abiAlignment(mod),
|
||||
else => decl_align,
|
||||
};
|
||||
if (!gop.found_existing or
|
||||
!required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value))
|
||||
{
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer gpa.free(name);
|
||||
const res = self.lowerConst(name, tv, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
|
||||
const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
|
||||
else => {
|
||||
// TODO improve error message
|
||||
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
|
||||
|
||||
@ -473,7 +473,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
// This is basically the same as lowerUnnamedConst.
|
||||
// example:
|
||||
// const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
@ -484,15 +484,21 @@ pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.Src
|
||||
// to put it in some location.
|
||||
// ...
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
if (!gop.found_existing) {
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const required_alignment = switch (decl_align) {
|
||||
.none => ty.abiAlignment(mod),
|
||||
else => decl_align,
|
||||
};
|
||||
if (!gop.found_existing or
|
||||
required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt))
|
||||
{
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer gpa.free(name);
|
||||
const res = self.lowerConst(name, tv, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
|
||||
const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
|
||||
else => {
|
||||
// TODO improve error message
|
||||
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
|
||||
@ -3479,7 +3485,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
|
||||
const index = unnamed_consts.items.len;
|
||||
const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
|
||||
defer gpa.free(name);
|
||||
const sym_index = switch (try self.lowerConst(name, typed_value, self.zig_rodata_section_index.?, decl.srcLoc(mod))) {
|
||||
const sym_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.zig_rodata_section_index.?, decl.srcLoc(mod))) {
|
||||
.ok => |sym_index| sym_index,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
@ -3502,6 +3508,7 @@ fn lowerConst(
|
||||
self: *Elf,
|
||||
name: []const u8,
|
||||
tv: TypedValue,
|
||||
required_alignment: InternPool.Alignment,
|
||||
output_section_index: u16,
|
||||
src_loc: Module.SrcLoc,
|
||||
) !LowerConstResult {
|
||||
@ -3510,7 +3517,6 @@ fn lowerConst(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const mod = self.base.options.module.?;
|
||||
const zig_module = self.file(self.zig_module_index.?).?.zig_module;
|
||||
const sym_index = try zig_module.addAtom(self);
|
||||
|
||||
@ -3524,7 +3530,6 @@ fn lowerConst(
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
|
||||
const required_alignment = tv.ty.abiAlignment(mod);
|
||||
const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;
|
||||
const local_sym = self.symbol(sym_index);
|
||||
const name_str_index = try self.strtab.insert(gpa, name);
|
||||
|
||||
@ -2196,7 +2196,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
|
||||
const index = unnamed_consts.items.len;
|
||||
const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index });
|
||||
defer gpa.free(name);
|
||||
const atom_index = switch (try self.lowerConst(name, typed_value, self.data_const_section_index.?, decl.srcLoc(mod))) {
|
||||
const atom_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.data_const_section_index.?, decl.srcLoc(mod))) {
|
||||
.ok => |atom_index| atom_index,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
@ -2219,6 +2219,7 @@ fn lowerConst(
|
||||
self: *MachO,
|
||||
name: []const u8,
|
||||
tv: TypedValue,
|
||||
required_alignment: InternPool.Alignment,
|
||||
sect_id: u8,
|
||||
src_loc: Module.SrcLoc,
|
||||
) !LowerConstResult {
|
||||
@ -2227,8 +2228,6 @@ fn lowerConst(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const mod = self.base.options.module.?;
|
||||
|
||||
log.debug("allocating symbol indexes for {s}", .{name});
|
||||
|
||||
const sym_index = try self.allocateSymbol();
|
||||
@ -2243,7 +2242,6 @@ fn lowerConst(
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
|
||||
const required_alignment = tv.ty.abiAlignment(mod);
|
||||
const atom = self.getAtomPtr(atom_index);
|
||||
atom.size = code.len;
|
||||
// TODO: work out logic for disambiguating functions from function pointers
|
||||
@ -2868,7 +2866,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
|
||||
return 0;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
// This is basically the same as lowerUnnamedConst.
|
||||
// example:
|
||||
// const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
@ -2879,15 +2877,21 @@ pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.S
|
||||
// to put it in some location.
|
||||
// ...
|
||||
const gpa = self.base.allocator;
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
|
||||
if (!gop.found_existing) {
|
||||
const mod = self.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const required_alignment = switch (decl_align) {
|
||||
.none => ty.abiAlignment(mod),
|
||||
else => decl_align,
|
||||
};
|
||||
if (!gop.found_existing or
|
||||
!required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value))
|
||||
{
|
||||
const val = decl_val.toValue();
|
||||
const tv = TypedValue{ .ty = ty, .val = val };
|
||||
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer gpa.free(name);
|
||||
const res = self.lowerConst(name, tv, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
|
||||
const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
|
||||
else => {
|
||||
// TODO improve error message
|
||||
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
|
||||
|
||||
@ -1702,25 +1702,30 @@ pub fn getDeclVAddr(
|
||||
return target_symbol_index;
|
||||
}
|
||||
|
||||
pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result {
|
||||
const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
|
||||
if (gop.found_existing) {
|
||||
return .ok;
|
||||
if (!gop.found_existing) {
|
||||
const mod = wasm.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
|
||||
const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer wasm.base.allocator.free(name);
|
||||
|
||||
switch (try wasm.lowerConst(name, tv, src_loc)) {
|
||||
.ok => |atom_index| gop.value_ptr.* = atom_index,
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
}
|
||||
|
||||
const mod = wasm.base.options.module.?;
|
||||
const ty = mod.intern_pool.typeOf(decl_val).toType();
|
||||
const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
|
||||
const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
|
||||
defer wasm.base.allocator.free(name);
|
||||
|
||||
switch (try wasm.lowerConst(name, tv, src_loc)) {
|
||||
.ok => |atom_index| {
|
||||
gop.value_ptr.* = atom_index;
|
||||
return .ok;
|
||||
const atom = wasm.getAtomPtr(gop.value_ptr.*);
|
||||
atom.alignment = switch (atom.alignment) {
|
||||
.none => decl_align,
|
||||
else => switch (decl_align) {
|
||||
.none => atom.alignment,
|
||||
else => atom.alignment.maxStrict(decl_align),
|
||||
},
|
||||
.fail => |em| return .{ .fail = em },
|
||||
}
|
||||
};
|
||||
return .ok;
|
||||
}
|
||||
|
||||
pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user