authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-02 10:27:03+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-02 10:27:03+01:00
log8abbdb56a4fce176cb8ec24e5d4724ac16196a0b
tree90157927058b6e273bec741d04787623b828574c
parentfccf15fc9f77001c513946cd1f37e8f6a57188e1
parent79717740bdce162caa34936040cd774dbe4c15a2
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21729 from alexrp/target-cpu-baseline

`std.Target.Cpu.Model`: Further refinements to `generic()` and `baseline()`

3 files changed, 56 insertions(+), 13 deletions(-)

lib/std/Target.zig+36-9
......@@ -1878,6 +1878,9 @@ pub const Cpu = struct {
18781878 };
18791879 }
18801880
1881 /// Returns the most bare-bones CPU model that is valid for `arch`. Note that this function
1882 /// can return CPU models that are understood by LLVM, but *not* understood by Clang. If
1883 /// Clang compatibility is important, consider using `baseline` instead.
18811884 pub fn generic(arch: Arch) *const Model {
18821885 const S = struct {
18831886 const generic_model = Model{
......@@ -1887,10 +1890,11 @@ pub const Cpu = struct {
18871890 };
18881891 };
18891892 return switch (arch) {
1893 .amdgcn => &amdgpu.cpu.gfx600,
18901894 .arc => &arc.cpu.generic,
18911895 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
18921896 .aarch64, .aarch64_be => &aarch64.cpu.generic,
1893 .avr => &avr.cpu.avr2,
1897 .avr => &avr.cpu.avr1,
18941898 .bpfel, .bpfeb => &bpf.cpu.generic,
18951899 .csky => &csky.cpu.generic,
18961900 .hexagon => &hexagon.cpu.generic,
......@@ -1901,13 +1905,10 @@ pub const Cpu = struct {
19011905 .mips, .mipsel => &mips.cpu.mips32,
19021906 .mips64, .mips64el => &mips.cpu.mips64,
19031907 .msp430 => &msp430.cpu.generic,
1904 .powerpc => &powerpc.cpu.ppc,
1905 .powerpcle => &powerpc.cpu.ppc,
1906 .powerpc64 => &powerpc.cpu.ppc64,
1907 .powerpc64le => &powerpc.cpu.ppc64le,
1908 .powerpc, .powerpcle => &powerpc.cpu.ppc,
1909 .powerpc64, .powerpc64le => &powerpc.cpu.ppc64,
19081910 .propeller1 => &propeller.cpu.generic,
19091911 .propeller2 => &propeller.cpu.generic,
1910 .amdgcn => &amdgpu.cpu.generic,
19111912 .riscv32 => &riscv.cpu.generic_rv32,
19121913 .riscv64 => &riscv.cpu.generic_rv64,
19131914 .spirv, .spirv32, .spirv64 => &spirv.cpu.generic,
......@@ -1928,8 +1929,17 @@ pub const Cpu = struct {
19281929 };
19291930 }
19301931
1932 /// Returns a conservative CPU model for `arch` that is expected to be compatible with the
1933 /// vast majority of hardware available. This function is guaranteed to return CPU models
1934 /// that are understood by both LLVM and Clang, unlike `generic`.
1935 ///
1936 /// For certain `os` values, this function will additionally bump the baseline higher than
1937 /// the baseline would be for `arch` in isolation; for example, for `aarch64-macos`, the
1938 /// baseline is considered to be `apple_m1`. To avoid this behavior entirely, pass
1939 /// `Os.Tag.freestanding`.
19311940 pub fn baseline(arch: Arch, os: Os) *const Model {
19321941 return switch (arch) {
1942 .amdgcn => &amdgpu.cpu.gfx906,
19331943 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline,
19341944 .aarch64 => switch (os.tag) {
19351945 .bridgeos, .driverkit, .macos => &aarch64.cpu.apple_m1,
......@@ -1938,14 +1948,31 @@ pub const Cpu = struct {
19381948 .watchos => &aarch64.cpu.apple_s4,
19391949 else => generic(arch),
19401950 },
1951 .avr => &avr.cpu.avr2,
1952 .bpfel, .bpfeb => &bpf.cpu.v1,
1953 .csky => &csky.cpu.ck810, // gcc/clang do not have a generic csky model.
19411954 .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model.
1955 .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model.
1956 .loongarch64 => &loongarch.cpu.loongarch64,
1957 .m68k => &m68k.cpu.M68000,
1958 .mips, .mipsel => &mips.cpu.mips32r2,
1959 .mips64, .mips64el => &mips.cpu.mips64r2,
1960 .msp430 => &msp430.cpu.msp430,
1961 .nvptx, .nvptx64 => &nvptx.cpu.sm_52,
1962 .powerpc64le => &powerpc.cpu.ppc64le,
19421963 .riscv32 => &riscv.cpu.baseline_rv32,
19431964 .riscv64 => &riscv.cpu.baseline_rv64,
1944 .x86 => &x86.cpu.pentium4,
1945 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
19461965 .s390x => &s390x.cpu.arch8, // gcc/clang do not have a generic s390x model.
19471966 .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8.
1948 .loongarch64 => &loongarch.cpu.loongarch64,
1967 .x86 => &x86.cpu.pentium4,
1968 .x86_64 => switch (os.tag) {
1969 .driverkit => &x86.cpu.nehalem,
1970 .ios, .macos, .tvos, .visionos, .watchos => &x86.cpu.core2,
1971 .ps4 => &x86.cpu.btver2,
1972 .ps5 => &x86.cpu.znver2,
1973 else => generic(arch),
1974 },
1975 .xcore => &xcore.cpu.xs1b_generic,
19491976
19501977 else => generic(arch),
19511978 };
src/Compilation.zig+6-4
......@@ -5371,10 +5371,12 @@ pub fn addCCArgs(
53715371 try argv.append(include_dir);
53725372 }
53735373
5374 if (target.cpu.model.llvm_name) |llvm_name| {
5375 try argv.appendSlice(&[_][]const u8{
5376 "-Xclang", "-target-cpu", "-Xclang", llvm_name,
5377 });
5374 if (target_util.clangSupportsTargetCpuArg(target)) {
5375 if (target.cpu.model.llvm_name) |llvm_name| {
5376 try argv.appendSlice(&[_][]const u8{
5377 "-Xclang", "-target-cpu", "-Xclang", llvm_name,
5378 });
5379 }
53785380 }
53795381
53805382 // It would be really nice if there was a more compact way to communicate this info to Clang.
src/target.zig+14
......@@ -315,6 +315,20 @@ pub fn clangAssemblerSupportsMcpuArg(target: std.Target) bool {
315315 };
316316}
317317
318/// Some experimental or poorly-maintained LLVM targets do not properly process CPU models in their
319/// Clang driver code. For these, we should omit the `-Xclang -target-cpu -Xclang <model>` flags.
320pub fn clangSupportsTargetCpuArg(target: std.Target) bool {
321 return switch (target.cpu.arch) {
322 .arc,
323 .msp430,
324 .ve,
325 .xcore,
326 .xtensa,
327 => false,
328 else => true,
329 };
330}
331
318332pub fn clangSupportsFloatAbiArg(target: std.Target) bool {
319333 return switch (target.cpu.arch) {
320334 .arm,