mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
llvm: Replace DataLayoutBuilder with a simple target -> string switch.
This should be a lot easier to maintain. It's also a small step towards eventually making the builder API parse the data layout string in order to answer layout questions that we need to ask during code generation.
This commit is contained in:
parent
5c57e90ffb
commit
5466a2f72d
@ -100,7 +100,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
|
||||
.kalimba,
|
||||
.propeller,
|
||||
=> unreachable, // Gated by hasLlvmSupport().
|
||||
|
||||
};
|
||||
|
||||
try llvm_triple.appendSlice(llvm_arch);
|
||||
@ -309,467 +308,154 @@ pub fn supportsTailCall(target: std.Target) bool {
|
||||
}
|
||||
}
|
||||
|
||||
const DataLayoutBuilder = struct {
|
||||
target: std.Target,
|
||||
pub fn dataLayout(target: std.Target) []const u8 {
|
||||
// These data layouts should match Clang.
|
||||
return switch (target.cpu.arch) {
|
||||
.arc => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32",
|
||||
.xcore => "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32",
|
||||
.hexagon => "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048",
|
||||
.lanai => "E-m:e-p:32:32-i64:64-a:0:32-n32-S64",
|
||||
.aarch64 => if (target.ofmt == .macho)
|
||||
if (target.os.tag == .windows)
|
||||
"e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
else if (target.abi == .ilp32)
|
||||
"e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
else
|
||||
"e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
else if (target.os.tag == .windows)
|
||||
"e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
|
||||
else
|
||||
"e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
|
||||
.aarch64_be => "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
|
||||
.arm => if (target.ofmt == .macho)
|
||||
"e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
else
|
||||
"e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
|
||||
.armeb, .thumbeb => if (target.ofmt == .macho)
|
||||
"E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
else
|
||||
"E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
|
||||
.thumb => if (target.ofmt == .macho)
|
||||
"e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
else if (target.os.tag == .windows)
|
||||
"e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
else
|
||||
"e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
|
||||
.avr => "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
|
||||
.bpfeb => "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
.bpfel => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
.msp430 => "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16",
|
||||
.mips => "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
|
||||
.mipsel => "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
|
||||
.mips64 => switch (target.abi) {
|
||||
.gnuabin32, .muslabin32 => "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128",
|
||||
else => "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128",
|
||||
},
|
||||
.mips64el => switch (target.abi) {
|
||||
.gnuabin32, .muslabin32 => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128",
|
||||
else => "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128",
|
||||
},
|
||||
.m68k => "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",
|
||||
.powerpc => if (target.os.tag == .aix)
|
||||
"E-m:a-p:32:32-Fi32-i64:64-n32"
|
||||
else
|
||||
"E-m:e-p:32:32-Fn32-i64:64-n32",
|
||||
.powerpcle => "e-m:e-p:32:32-Fn32-i64:64-n32",
|
||||
.powerpc64 => switch (target.os.tag) {
|
||||
.aix => "E-m:a-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512",
|
||||
.linux => if (target.abi.isMusl())
|
||||
"E-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512"
|
||||
else
|
||||
"E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512",
|
||||
.ps3 => "E-m:e-p:32:32-Fi64-i64:64-n32:64",
|
||||
else => if (target.os.tag == .openbsd or
|
||||
(target.os.tag == .freebsd and target.os.version_range.semver.isAtLeast(.{ .major = 13, .minor = 0, .patch = 0 }) orelse false))
|
||||
"E-m:e-Fn32-i64:64-n32:64"
|
||||
else
|
||||
"E-m:e-Fi64-i64:64-n32:64",
|
||||
},
|
||||
.powerpc64le => if (target.os.tag == .linux)
|
||||
"e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512"
|
||||
else
|
||||
"e-m:e-Fn32-i64:64-n32:64",
|
||||
.nvptx => "e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64",
|
||||
.nvptx64 => "e-i64:64-i128:128-v16:16-v32:32-n16:32:64",
|
||||
.amdgcn => "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9",
|
||||
.riscv32 => if (std.Target.riscv.featureSetHas(target.cpu.features, .e))
|
||||
"e-m:e-p:32:32-i64:64-n32-S32"
|
||||
else
|
||||
"e-m:e-p:32:32-i64:64-n32-S128",
|
||||
.riscv64 => if (std.Target.riscv.featureSetHas(target.cpu.features, .e))
|
||||
"e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
|
||||
else
|
||||
"e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
.sparc => "E-m:e-p:32:32-i64:64-f128:64-n32-S64",
|
||||
.sparc64 => "E-m:e-i64:64-n32:64-S128",
|
||||
.s390x => if (target.os.tag == .zos)
|
||||
"E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
|
||||
else
|
||||
"E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64",
|
||||
.x86 => switch (target.os.tag) {
|
||||
.elfiamcu => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32",
|
||||
.windows => switch (target.abi) {
|
||||
.cygnus => "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32",
|
||||
.gnu => if (target.ofmt == .coff)
|
||||
"e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
|
||||
else
|
||||
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32",
|
||||
else => blk: {
|
||||
const msvc = switch (target.abi) {
|
||||
.none, .msvc => true,
|
||||
else => false,
|
||||
};
|
||||
|
||||
pub fn format(
|
||||
self: DataLayoutBuilder,
|
||||
comptime _: []const u8,
|
||||
_: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
try writer.writeByte(switch (self.target.cpu.arch.endian()) {
|
||||
.little => 'e',
|
||||
.big => 'E',
|
||||
});
|
||||
switch (self.target.cpu.arch) {
|
||||
.amdgcn,
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
=> {},
|
||||
.avr => try writer.writeAll("-P1"),
|
||||
else => try writer.print("-m:{c}", .{@as(u8, switch (self.target.cpu.arch) {
|
||||
.mips, .mipsel => 'm', // Mips mangling: Private symbols get a $ prefix.
|
||||
else => switch (self.target.ofmt) {
|
||||
.elf => 'e', // ELF mangling: Private symbols get a `.L` prefix.
|
||||
//.goff => 'l', // GOFF mangling: Private symbols get a `@` prefix.
|
||||
.macho => 'o', // Mach-O mangling: Private symbols get `L` prefix.
|
||||
// Other symbols get a `_` prefix.
|
||||
.coff => switch (self.target.os.tag) {
|
||||
.uefi, .windows => switch (self.target.cpu.arch) {
|
||||
.x86 => 'x', // Windows x86 COFF mangling: Private symbols get the usual
|
||||
// prefix. Regular C symbols get a `_` prefix. Functions with `__stdcall`,
|
||||
//`__fastcall`, and `__vectorcall` have custom mangling that appends `@N`
|
||||
// where N is the number of bytes used to pass parameters. C++ symbols
|
||||
// starting with `?` are not mangled in any way.
|
||||
else => 'w', // Windows COFF mangling: Similar to x, except that normal C
|
||||
// symbols do not receive a `_` prefix.
|
||||
},
|
||||
else => 'e',
|
||||
},
|
||||
//.xcoff => 'a', // XCOFF mangling: Private symbols get a `L..` prefix.
|
||||
else => 'e',
|
||||
break :blk if (target.ofmt == .coff)
|
||||
if (msvc)
|
||||
"e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
|
||||
else
|
||||
"e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
|
||||
else if (msvc)
|
||||
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32-a:0:32-S32"
|
||||
else
|
||||
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32";
|
||||
},
|
||||
})}),
|
||||
}
|
||||
const stack_abi = self.target.stackAlignment() * 8;
|
||||
if (self.target.cpu.arch == .csky) try writer.print("-S{d}", .{stack_abi});
|
||||
var any_non_integral = false;
|
||||
const ptr_bit_width = self.target.ptrBitWidth();
|
||||
var default_info = struct { size: u16, abi: u16, pref: u16, idx: u16 }{
|
||||
.size = 64,
|
||||
.abi = 64,
|
||||
.pref = 64,
|
||||
.idx = 64,
|
||||
};
|
||||
const addr_space_info = llvmAddrSpaceInfo(self.target);
|
||||
for (addr_space_info, 0..) |info, i| {
|
||||
assert((info.llvm == .default) == (i == 0));
|
||||
if (info.non_integral) {
|
||||
assert(info.llvm != .default);
|
||||
any_non_integral = true;
|
||||
}
|
||||
const size = info.size orelse ptr_bit_width;
|
||||
const abi = info.abi orelse ptr_bit_width;
|
||||
const pref = info.pref orelse abi;
|
||||
const idx = info.idx orelse size;
|
||||
const matches_default =
|
||||
size == default_info.size and
|
||||
abi == default_info.abi and
|
||||
pref == default_info.pref and
|
||||
idx == default_info.idx;
|
||||
if (info.llvm == .default) default_info = .{
|
||||
.size = size,
|
||||
.abi = abi,
|
||||
.pref = pref,
|
||||
.idx = idx,
|
||||
};
|
||||
if (!info.force_in_data_layout and matches_default and
|
||||
self.target.cpu.arch != .riscv64 and
|
||||
self.target.cpu.arch != .loongarch64 and
|
||||
!(self.target.cpu.arch == .aarch64 and
|
||||
(self.target.os.tag == .uefi or self.target.os.tag == .windows)) and
|
||||
self.target.cpu.arch != .bpfeb and self.target.cpu.arch != .bpfel) continue;
|
||||
try writer.writeAll("-p");
|
||||
if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)});
|
||||
try writer.print(":{d}:{d}", .{ size, abi });
|
||||
if (pref != abi or idx != size or self.target.cpu.arch == .hexagon) {
|
||||
try writer.print(":{d}", .{pref});
|
||||
if (idx != size) try writer.print(":{d}", .{idx});
|
||||
}
|
||||
}
|
||||
if (self.target.cpu.arch.isArm())
|
||||
try writer.writeAll("-Fi8") // for thumb interwork
|
||||
else if (self.target.cpu.arch == .powerpc64 and
|
||||
self.target.os.tag != .freebsd and
|
||||
self.target.os.tag != .openbsd and
|
||||
!self.target.abi.isMusl())
|
||||
try writer.writeAll("-Fi64")
|
||||
else if (self.target.cpu.arch.isPowerPC() and self.target.os.tag == .aix)
|
||||
try writer.writeAll(if (self.target.cpu.arch.isPowerPC64()) "-Fi64" else "-Fi32")
|
||||
else if (self.target.cpu.arch.isPowerPC())
|
||||
try writer.writeAll("-Fn32");
|
||||
if (self.target.cpu.arch != .hexagon) {
|
||||
if (self.target.cpu.arch == .arc or self.target.cpu.arch == .s390x)
|
||||
try self.typeAlignment(.integer, 1, 8, 8, false, writer);
|
||||
try self.typeAlignment(.integer, 8, 8, 8, false, writer);
|
||||
try self.typeAlignment(.integer, 16, 16, 16, false, writer);
|
||||
try self.typeAlignment(.integer, 32, 32, 32, false, writer);
|
||||
if (self.target.cpu.arch == .arc)
|
||||
try self.typeAlignment(.float, 32, 32, 32, false, writer);
|
||||
try self.typeAlignment(.integer, 64, 32, 64, false, writer);
|
||||
try self.typeAlignment(.integer, 128, 32, 64, false, writer);
|
||||
if (backendSupportsF16(self.target))
|
||||
try self.typeAlignment(.float, 16, 16, 16, false, writer);
|
||||
if (self.target.cpu.arch != .arc)
|
||||
try self.typeAlignment(.float, 32, 32, 32, false, writer);
|
||||
try self.typeAlignment(.float, 64, 64, 64, false, writer);
|
||||
if (self.target.cpu.arch.isX86()) try self.typeAlignment(.float, 80, 0, 0, false, writer);
|
||||
try self.typeAlignment(.float, 128, 128, 128, false, writer);
|
||||
}
|
||||
switch (self.target.cpu.arch) {
|
||||
.amdgcn => {
|
||||
try self.typeAlignment(.vector, 16, 16, 16, false, writer);
|
||||
try self.typeAlignment(.vector, 24, 32, 32, false, writer);
|
||||
try self.typeAlignment(.vector, 32, 32, 32, false, writer);
|
||||
try self.typeAlignment(.vector, 48, 64, 64, false, writer);
|
||||
try self.typeAlignment(.vector, 96, 128, 128, false, writer);
|
||||
try self.typeAlignment(.vector, 192, 256, 256, false, writer);
|
||||
try self.typeAlignment(.vector, 256, 256, 256, false, writer);
|
||||
try self.typeAlignment(.vector, 512, 512, 512, false, writer);
|
||||
try self.typeAlignment(.vector, 1024, 1024, 1024, false, writer);
|
||||
try self.typeAlignment(.vector, 2048, 2048, 2048, false, writer);
|
||||
},
|
||||
.ve => {},
|
||||
else => {
|
||||
try self.typeAlignment(.vector, 16, 32, 32, false, writer);
|
||||
try self.typeAlignment(.vector, 32, 32, 32, false, writer);
|
||||
try self.typeAlignment(.vector, 64, 64, 64, false, writer);
|
||||
try self.typeAlignment(.vector, 128, 128, 128, true, writer);
|
||||
},
|
||||
}
|
||||
const swap_agg_nat = switch (self.target.cpu.arch) {
|
||||
.x86, .x86_64 => switch (self.target.os.tag) {
|
||||
.uefi, .windows => true,
|
||||
else => false,
|
||||
},
|
||||
.avr, .m68k => true,
|
||||
else => false,
|
||||
};
|
||||
if (!swap_agg_nat) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer);
|
||||
if (self.target.cpu.arch == .csky) try writer.writeAll("-Fi32");
|
||||
for (@as([]const u24, switch (self.target.cpu.arch) {
|
||||
.avr => &.{8},
|
||||
.msp430 => &.{ 8, 16 },
|
||||
.arc,
|
||||
.arm,
|
||||
.armeb,
|
||||
.csky,
|
||||
.loongarch32,
|
||||
.mips,
|
||||
.mipsel,
|
||||
.powerpc,
|
||||
.powerpcle,
|
||||
.riscv32,
|
||||
.sparc,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
.xtensa,
|
||||
=> &.{32},
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
.amdgcn,
|
||||
.bpfeb,
|
||||
.bpfel,
|
||||
.loongarch64,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
.powerpc64,
|
||||
.powerpc64le,
|
||||
.riscv64,
|
||||
.s390x,
|
||||
.sparc64,
|
||||
.ve,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
=> &.{ 32, 64 },
|
||||
.hexagon => &.{ 16, 32 },
|
||||
.m68k,
|
||||
.x86,
|
||||
=> &.{ 8, 16, 32 },
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
=> &.{ 16, 32, 64 },
|
||||
.x86_64 => &.{ 8, 16, 32, 64 },
|
||||
else => &.{},
|
||||
}), 0..) |natural, index| switch (index) {
|
||||
0 => try writer.print("-n{d}", .{natural}),
|
||||
else => try writer.print(":{d}", .{natural}),
|
||||
};
|
||||
if (swap_agg_nat) try self.typeAlignment(.aggregate, 0, 0, 64, false, writer);
|
||||
if (self.target.cpu.arch == .hexagon) {
|
||||
try self.typeAlignment(.integer, 64, 64, 64, true, writer);
|
||||
try self.typeAlignment(.integer, 32, 32, 32, true, writer);
|
||||
try self.typeAlignment(.integer, 16, 16, 16, true, writer);
|
||||
try self.typeAlignment(.integer, 1, 8, 8, true, writer);
|
||||
try self.typeAlignment(.float, 32, 32, 32, true, writer);
|
||||
try self.typeAlignment(.float, 64, 64, 64, true, writer);
|
||||
}
|
||||
if (stack_abi != ptr_bit_width or self.target.cpu.arch == .msp430 or
|
||||
self.target.os.tag == .uefi or self.target.os.tag == .windows or
|
||||
self.target.cpu.arch == .riscv32)
|
||||
try writer.print("-S{d}", .{stack_abi});
|
||||
if (self.target.cpu.arch.isAARCH64())
|
||||
try writer.writeAll("-Fn32");
|
||||
switch (self.target.cpu.arch) {
|
||||
.hexagon, .ve => {
|
||||
try self.typeAlignment(.vector, 32, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 64, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 128, 128, 128, true, writer);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
if (self.target.cpu.arch != .amdgcn) {
|
||||
try self.typeAlignment(.vector, 256, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 512, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 1024, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 2048, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 4096, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 8192, 128, 128, true, writer);
|
||||
try self.typeAlignment(.vector, 16384, 128, 128, true, writer);
|
||||
}
|
||||
const alloca_addr_space = llvmAllocaAddressSpace(self.target);
|
||||
if (alloca_addr_space != .default) try writer.print("-A{d}", .{@intFromEnum(alloca_addr_space)});
|
||||
const global_addr_space = llvmDefaultGlobalAddressSpace(self.target);
|
||||
if (global_addr_space != .default) try writer.print("-G{d}", .{@intFromEnum(global_addr_space)});
|
||||
if (any_non_integral) {
|
||||
try writer.writeAll("-ni");
|
||||
for (addr_space_info) |info| if (info.non_integral)
|
||||
try writer.print(":{d}", .{@intFromEnum(info.llvm)});
|
||||
}
|
||||
}
|
||||
else => if (target.ofmt == .macho)
|
||||
"e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
|
||||
else
|
||||
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128",
|
||||
},
|
||||
.x86_64 => if (target.os.tag.isDarwin() or target.ofmt == .macho)
|
||||
"e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
else switch (target.abi) {
|
||||
.gnux32, .muslx32 => "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
|
||||
else => if (target.os.tag == .windows and target.ofmt == .coff)
|
||||
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
||||
else
|
||||
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
|
||||
},
|
||||
.spirv => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
|
||||
.spirv32 => "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
|
||||
.spirv64 => "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1",
|
||||
.wasm32 => if (target.os.tag == .emscripten)
|
||||
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-S128-ni:1:10:20"
|
||||
else
|
||||
"e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20",
|
||||
.wasm64 => if (target.os.tag == .emscripten)
|
||||
"e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-S128-ni:1:10:20"
|
||||
else
|
||||
"e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20",
|
||||
.ve => "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64",
|
||||
.csky => "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32",
|
||||
.loongarch32 => "e-m:e-p:32:32-i64:64-n32-S128",
|
||||
.loongarch64 => "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
.xtensa => "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32",
|
||||
|
||||
fn typeAlignment(
|
||||
self: DataLayoutBuilder,
|
||||
kind: enum { integer, vector, float, aggregate },
|
||||
size: u24,
|
||||
default_abi: u24,
|
||||
default_pref: u24,
|
||||
default_force_pref: bool,
|
||||
writer: anytype,
|
||||
) @TypeOf(writer).Error!void {
|
||||
var abi = default_abi;
|
||||
var pref = default_pref;
|
||||
var force_abi = false;
|
||||
var force_pref = default_force_pref;
|
||||
if (kind == .float and size == 80) {
|
||||
abi = 128;
|
||||
pref = 128;
|
||||
}
|
||||
for (@as([]const std.Target.CType, switch (kind) {
|
||||
.integer => &.{ .char, .short, .int, .long, .longlong },
|
||||
.float => &.{ .float, .double, .longdouble },
|
||||
.vector, .aggregate => &.{},
|
||||
})) |cty| {
|
||||
if (self.target.cTypeBitSize(cty) != size) continue;
|
||||
abi = self.target.cTypeAlignment(cty) * 8;
|
||||
pref = self.target.cTypePreferredAlignment(cty) * 8;
|
||||
break;
|
||||
}
|
||||
switch (kind) {
|
||||
.integer => {
|
||||
if (self.target.ptrBitWidth() <= 16 and size >= 128) return;
|
||||
abi = @min(abi, Type.maxIntAlignment(self.target) * 8);
|
||||
switch (self.target.cpu.arch) {
|
||||
.aarch64,
|
||||
.aarch64_be,
|
||||
=> if (size == 128) {
|
||||
abi = size;
|
||||
pref = size;
|
||||
} else switch (self.target.os.tag) {
|
||||
.macos, .ios, .watchos, .tvos, .visionos => {},
|
||||
.uefi, .windows => {
|
||||
pref = size;
|
||||
force_abi = size >= 32;
|
||||
},
|
||||
else => pref = @max(pref, 32),
|
||||
},
|
||||
.arc => if (size <= 64) {
|
||||
abi = @min((std.math.divCeil(u24, size, 8) catch unreachable) * 8, 32);
|
||||
pref = 32;
|
||||
force_abi = true;
|
||||
force_pref = size <= 32;
|
||||
},
|
||||
.bpfeb,
|
||||
.bpfel,
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
.riscv64,
|
||||
=> if (size == 128) {
|
||||
abi = size;
|
||||
pref = size;
|
||||
},
|
||||
.csky => if (size == 32 or size == 64) {
|
||||
abi = 32;
|
||||
pref = 32;
|
||||
force_abi = true;
|
||||
force_pref = true;
|
||||
},
|
||||
.hexagon => force_abi = true,
|
||||
.m68k => if (size <= 32) {
|
||||
abi = @min(size, 16);
|
||||
pref = size;
|
||||
force_abi = true;
|
||||
force_pref = true;
|
||||
} else if (size == 64) {
|
||||
abi = 32;
|
||||
pref = size;
|
||||
},
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> pref = @max(pref, 32),
|
||||
.s390x => pref = @max(pref, 16),
|
||||
.ve => if (size == 64) {
|
||||
abi = size;
|
||||
pref = size;
|
||||
},
|
||||
.xtensa => if (size <= 64) {
|
||||
pref = @max(size, 32);
|
||||
abi = size;
|
||||
force_abi = size == 64;
|
||||
},
|
||||
.x86 => switch (size) {
|
||||
128 => {
|
||||
abi = size;
|
||||
pref = size;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.x86_64 => switch (size) {
|
||||
64, 128 => {
|
||||
abi = size;
|
||||
pref = size;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.loongarch64 => switch (size) {
|
||||
128 => {
|
||||
abi = size;
|
||||
pref = size;
|
||||
force_abi = true;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
.vector => if (self.target.cpu.arch.isArm()) {
|
||||
switch (size) {
|
||||
128 => abi = 64,
|
||||
else => {},
|
||||
}
|
||||
} else if ((self.target.cpu.arch.isPowerPC64() and self.target.os.tag == .linux and
|
||||
(size == 256 or size == 512)) or
|
||||
(self.target.cpu.arch.isNvptx() and (size == 16 or size == 32)))
|
||||
{
|
||||
force_abi = true;
|
||||
abi = size;
|
||||
pref = size;
|
||||
} else if (self.target.cpu.arch == .amdgcn and size <= 2048) {
|
||||
force_abi = true;
|
||||
} else if (self.target.cpu.arch == .csky and (size == 64 or size == 128)) {
|
||||
abi = 32;
|
||||
pref = 32;
|
||||
force_pref = true;
|
||||
} else if (self.target.cpu.arch == .hexagon and
|
||||
((size >= 32 and size <= 64) or (size >= 512 and size <= 2048)))
|
||||
{
|
||||
abi = size;
|
||||
pref = size;
|
||||
force_pref = true;
|
||||
} else if (self.target.cpu.arch == .s390x and size == 128) {
|
||||
abi = 64;
|
||||
pref = 64;
|
||||
force_pref = false;
|
||||
} else if (self.target.cpu.arch == .ve and (size >= 64 and size <= 16384)) {
|
||||
abi = 64;
|
||||
pref = 64;
|
||||
force_abi = true;
|
||||
force_pref = true;
|
||||
},
|
||||
.float => switch (self.target.cpu.arch) {
|
||||
.amdgcn => if (size == 128) {
|
||||
abi = size;
|
||||
pref = size;
|
||||
},
|
||||
.arc => if (size == 32 or size == 64) {
|
||||
abi = 32;
|
||||
pref = 32;
|
||||
force_abi = true;
|
||||
force_pref = size == 32;
|
||||
},
|
||||
.avr, .msp430, .sparc64 => if (size != 32 and size != 64) return,
|
||||
.csky => if (size == 32 or size == 64) {
|
||||
abi = 32;
|
||||
pref = 32;
|
||||
force_abi = true;
|
||||
force_pref = true;
|
||||
},
|
||||
.hexagon => if (size == 32 or size == 64) {
|
||||
force_abi = true;
|
||||
},
|
||||
.ve, .xtensa => if (size == 64) {
|
||||
abi = size;
|
||||
pref = size;
|
||||
},
|
||||
.wasm32, .wasm64 => if (self.target.os.tag == .emscripten and size == 128) {
|
||||
abi = 64;
|
||||
pref = 64;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.aggregate => if (self.target.os.tag == .uefi or self.target.os.tag == .windows or
|
||||
self.target.cpu.arch.isArm())
|
||||
{
|
||||
pref = @min(pref, self.target.ptrBitWidth());
|
||||
} else switch (self.target.cpu.arch) {
|
||||
.arc, .csky => {
|
||||
abi = 0;
|
||||
pref = 32;
|
||||
},
|
||||
.hexagon => {
|
||||
abi = 0;
|
||||
pref = 0;
|
||||
},
|
||||
.m68k => {
|
||||
abi = 0;
|
||||
pref = 16;
|
||||
},
|
||||
.msp430 => {
|
||||
abi = 8;
|
||||
pref = 8;
|
||||
},
|
||||
.s390x => {
|
||||
abi = 8;
|
||||
pref = 16;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
}
|
||||
if (kind != .vector and self.target.cpu.arch == .avr) {
|
||||
force_abi = true;
|
||||
abi = 8;
|
||||
pref = 8;
|
||||
}
|
||||
if (!force_abi and abi == default_abi and pref == default_pref) return;
|
||||
try writer.print("-{c}", .{@tagName(kind)[0]});
|
||||
if (size != 0) try writer.print("{d}", .{size});
|
||||
try writer.print(":{d}", .{abi});
|
||||
if (pref != abi or force_pref) try writer.print(":{d}", .{pref});
|
||||
}
|
||||
};
|
||||
.kalimba,
|
||||
.propeller,
|
||||
=> unreachable, // Gated by hasLlvmSupport().
|
||||
};
|
||||
}
|
||||
|
||||
pub const Object = struct {
|
||||
gpa: Allocator,
|
||||
@ -856,7 +542,7 @@ pub const Object = struct {
|
||||
});
|
||||
errdefer builder.deinit();
|
||||
|
||||
builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
|
||||
builder.data_layout = try builder.string(dataLayout(target));
|
||||
|
||||
const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =
|
||||
if (!builder.strip) debug_info: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user