authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-18 05:25:36+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-06-05 06:12:00+02:00
log9d534790ebc869ec933e932abe4be8b9e3593bbc
tree70652dde381fd0c0d536d8e7665e725e0924bb51
parent14873f9a3434a0d753ca8438f389a7931956cf26

std.Target: Introduce Cpu convenience functions for feature tests.

Before: * std.Target.arm.featureSetHas(target.cpu.features, .has_v7) * std.Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }) * std.Target.wasm.featureSetHasAll(target.cpu.features, .{ .atomics, .bulk_memory }) After: * target.cpu.has(.arm, .has_v7) * target.cpu.hasAny(.x86, &.{ .sse, .avx, .cmov }) * target.cpu.hasAll(.wasm, &.{ .atomics, .bulk_memory })

53 files changed, 373 insertions(+), 393 deletions(-)

lib/compiler/aro/aro/target.zig+8-8
......@@ -162,7 +162,7 @@ pub fn ignoreNonZeroSizedBitfieldTypeAlignment(target: std.Target) bool {
162162 switch (target.cpu.arch) {
163163 .avr => return true,
164164 .arm => {
165 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
165 if (target.cpu.has(.arm, .has_v7)) {
166166 switch (target.os.tag) {
167167 .ios => return true,
168168 else => return false,
......@@ -185,7 +185,7 @@ pub fn minZeroWidthBitfieldAlignment(target: std.Target) ?u29 {
185185 switch (target.cpu.arch) {
186186 .avr => return 8,
187187 .arm => {
188 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
188 if (target.cpu.has(.arm, .has_v7)) {
189189 switch (target.os.tag) {
190190 .ios => return 32,
191191 else => return null,
......@@ -203,7 +203,7 @@ pub fn unnamedFieldAffectsAlignment(target: std.Target) bool {
203203 return true;
204204 },
205205 .armeb => {
206 if (std.Target.arm.featureSetHas(target.cpu.features, .has_v7)) {
206 if (target.cpu.has(.arm, .has_v7)) {
207207 if (std.Target.Abi.default(target.cpu.arch, target.os.tag) == .eabi) return true;
208208 }
209209 },
......@@ -230,7 +230,7 @@ pub fn defaultAlignment(target: std.Target) u29 {
230230 switch (target.cpu.arch) {
231231 .avr => return 1,
232232 .arm => if (target.abi.isAndroid() or target.os.tag == .ios) return 16 else return 8,
233 .sparc => if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) return 16 else return 8,
233 .sparc => if (target.cpu.has(.sparc, .v9)) return 16 else return 8,
234234 .mips, .mipsel => switch (target.abi) {
235235 .none, .gnuabi64 => return 16,
236236 else => return 8,
......@@ -268,7 +268,7 @@ pub fn systemCompiler(target: std.Target) LangOpts.Compiler {
268268pub fn hasFloat128(target: std.Target) bool {
269269 if (target.cpu.arch.isWasm()) return true;
270270 if (target.os.tag.isDarwin()) return false;
271 if (target.cpu.arch.isPowerPC()) return std.Target.powerpc.featureSetHas(target.cpu.features, .float128);
271 if (target.cpu.arch.isPowerPC()) return target.cpu.has(.powerpc, .float128);
272272 return switch (target.os.tag) {
273273 .dragonfly,
274274 .haiku,
......@@ -334,7 +334,7 @@ pub const FPSemantics = enum {
334334 .spirv32,
335335 .spirv64,
336336 => return .IEEEHalf,
337 .x86, .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .sse2)) return .IEEEHalf,
337 .x86, .x86_64 => if (target.cpu.has(.x86, .sse2)) return .IEEEHalf,
338338 else => {},
339339 }
340340 return null;
......@@ -399,7 +399,7 @@ pub fn defaultFpEvalMethod(target: std.Target) LangOpts.FPEvalMethod {
399399 return .double;
400400 }
401401 }
402 if (std.Target.x86.featureSetHas(target.cpu.features, .sse)) {
402 if (target.cpu.has(.x86, .sse)) {
403403 return .source;
404404 }
405405 return .extended;
......@@ -765,7 +765,7 @@ test "target size/align tests" {
765765 .specifier = .char,
766766 };
767767
768 try std.testing.expectEqual(true, std.Target.arm.featureSetHas(comp.target.cpu.features, .has_v7));
768 try std.testing.expectEqual(true, comp.target.cpu.has(.arm, .has_v7));
769769 try std.testing.expectEqual(@as(u64, 1), ct.sizeof(&comp).?);
770770 try std.testing.expectEqual(@as(u64, 1), ct.alignof(&comp));
771771 try std.testing.expectEqual(true, ignoreNonZeroSizedBitfieldTypeAlignment(comp.target));
lib/compiler/aro/aro/toolchains/Linux.zig+1-1
......@@ -318,7 +318,7 @@ pub fn buildLinkerArgs(self: *const Linux, tc: *const Toolchain, argv: *std.Arra
318318
319319fn getMultiarchTriple(target: std.Target) ?[]const u8 {
320320 const is_android = target.abi.isAndroid();
321 const is_mips_r6 = std.Target.mips.featureSetHas(target.cpu.features, .mips32r6);
321 const is_mips_r6 = target.cpu.has(.mips, .mips32r6);
322322 return switch (target.cpu.arch) {
323323 .arm, .thumb => if (is_android) "arm-linux-androideabi" else if (target.abi == .gnueabihf) "arm-linux-gnueabihf" else "arm-linux-gnueabi",
324324 .armeb, .thumbeb => if (target.abi == .gnueabihf) "armeb-linux-gnueabihf" else "armeb-linux-gnueabi",
lib/compiler_rt/aarch64_outline_atomics.zig+1-1
......@@ -2,7 +2,7 @@
22const builtin = @import("builtin");
33const std = @import("std");
44const common = @import("common.zig");
5const always_has_lse = std.Target.aarch64.featureSetHas(builtin.cpu.features, .lse);
5const always_has_lse = builtin.cpu.has(.aarch64, .lse);
66
77/// This default is overridden at runtime after inspecting CPU properties.
88/// It is intentionally not exported in order to make the machine code that
lib/compiler_rt/atomics.zig+2-2
......@@ -19,7 +19,7 @@ const supports_atomic_ops = switch (arch) {
1919 // operations (unless we're targeting Linux, the kernel provides a way to
2020 // perform CAS operations).
2121 // XXX: The Linux code path is not implemented yet.
22 !std.Target.arm.featureSetHas(builtin.cpu.features, .has_v6m),
22 !builtin.cpu.has(.arm, .has_v6m),
2323 else => true,
2424};
2525
......@@ -30,7 +30,7 @@ const largest_atomic_size = switch (arch) {
3030 // On SPARC systems that lacks CAS and/or swap instructions, the only
3131 // available atomic operation is a test-and-set (`ldstub`), so we force
3232 // every atomic memory access to go through the lock.
33 .sparc => if (std.Target.sparc.featureSetHas(builtin.cpu.features, .hasleoncasa)) @sizeOf(usize) else 0,
33 .sparc => if (builtin.cpu.has(.sparc, .hasleoncasa)) @sizeOf(usize) else 0,
3434
3535 // XXX: On x86/x86_64 we could check the presence of cmpxchg8b/cmpxchg16b
3636 // and set this parameter accordingly.
lib/compiler_rt/common.zig+1-1
......@@ -124,7 +124,7 @@ pub fn F16T(comptime OtherType: type) type {
124124 .spirv32,
125125 .spirv64,
126126 => f16,
127 .hexagon => if (std.Target.hexagon.featureSetHas(builtin.target.cpu.features, .v68)) f16 else u16,
127 .hexagon => if (builtin.target.cpu.has(.hexagon, .v68)) f16 else u16,
128128 .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) {
129129 // Starting with LLVM 16, Darwin uses different abi for f16
130130 // depending on the type of the other return/argument..???
lib/compiler_rt/count0bits.zig+1-3
......@@ -142,9 +142,7 @@ fn clzsi2_generic(a: i32) callconv(.c) i32 {
142142pub const __clzsi2 = switch (builtin.cpu.arch) {
143143 .arm, .armeb, .thumb, .thumbeb => impl: {
144144 const use_thumb1 =
145 (builtin.cpu.arch.isThumb() or
146 std.Target.arm.featureSetHas(builtin.cpu.features, .noarm)) and
147 !std.Target.arm.featureSetHas(builtin.cpu.features, .thumb2);
145 (builtin.cpu.arch.isThumb() or builtin.cpu.has(.arm, .noarm)) and !builtin.cpu.has(.arm, .thumb2);
148146
149147 if (use_thumb1) {
150148 break :impl __clzsi2_thumb1;
lib/std/Target.zig+113-117
......@@ -767,25 +767,27 @@ pub const Os = struct {
767767};
768768
769769pub const aarch64 = @import("Target/aarch64.zig");
770pub const arc = @import("Target/arc.zig");
771770pub const amdgcn = @import("Target/amdgcn.zig");
771pub const arc = @import("Target/arc.zig");
772772pub const arm = @import("Target/arm.zig");
773773pub const avr = @import("Target/avr.zig");
774774pub const bpf = @import("Target/bpf.zig");
775775pub const csky = @import("Target/csky.zig");
776776pub const hexagon = @import("Target/hexagon.zig");
777pub const kalimba = @import("Target/generic.zig");
777778pub const lanai = @import("Target/lanai.zig");
778779pub const loongarch = @import("Target/loongarch.zig");
779780pub const m68k = @import("Target/m68k.zig");
780781pub const mips = @import("Target/mips.zig");
781782pub const msp430 = @import("Target/msp430.zig");
782783pub const nvptx = @import("Target/nvptx.zig");
784pub const or1k = @import("Target/generic.zig");
783785pub const powerpc = @import("Target/powerpc.zig");
784786pub const propeller = @import("Target/propeller.zig");
785787pub const riscv = @import("Target/riscv.zig");
788pub const s390x = @import("Target/s390x.zig");
786789pub const sparc = @import("Target/sparc.zig");
787790pub const spirv = @import("Target/spirv.zig");
788pub const s390x = @import("Target/s390x.zig");
789791pub const ve = @import("Target/ve.zig");
790792pub const wasm = @import("Target/wasm.zig");
791793pub const x86 = @import("Target/x86.zig");
......@@ -1094,7 +1096,7 @@ pub fn toElfMachine(target: Target) std.elf.EM {
10941096 .propeller => .PROPELLER,
10951097 .riscv32, .riscv64 => .RISCV,
10961098 .s390x => .S390,
1097 .sparc => if (Target.sparc.featureSetHas(target.cpu.features, .v9)) .SPARC32PLUS else .SPARC,
1099 .sparc => if (target.cpu.has(.sparc, .v9)) .SPARC32PLUS else .SPARC,
10981100 .sparc64 => .SPARCV9,
10991101 .ve => .VE,
11001102 .x86 => .@"386",
......@@ -1396,6 +1398,71 @@ pub const Cpu = struct {
13961398 // - tce
13971399 // - tcele
13981400
1401 /// An architecture family can encompass multiple architectures as represented by `Arch`.
1402 /// For a given family tag, it is guaranteed that an `std.Target.<tag>` namespace exists
1403 /// containing CPU model and feature data.
1404 pub const Family = enum {
1405 amdgcn,
1406 arc,
1407 arm,
1408 aarch64,
1409 avr,
1410 bpf,
1411 csky,
1412 hexagon,
1413 kalimba,
1414 lanai,
1415 loongarch,
1416 m68k,
1417 mips,
1418 msp430,
1419 nvptx,
1420 or1k,
1421 powerpc,
1422 propeller,
1423 riscv,
1424 s390x,
1425 sparc,
1426 spirv,
1427 ve,
1428 wasm,
1429 x86,
1430 xcore,
1431 xtensa,
1432 };
1433
1434 pub inline fn family(arch: Arch) Family {
1435 return switch (arch) {
1436 .amdgcn => .amdgcn,
1437 .arc => .arc,
1438 .arm, .armeb, .thumb, .thumbeb => .arm,
1439 .aarch64, .aarch64_be => .aarch64,
1440 .avr => .avr,
1441 .bpfel, .bpfeb => .bpf,
1442 .csky => .csky,
1443 .hexagon => .hexagon,
1444 .kalimba => .kalimba,
1445 .lanai => .lanai,
1446 .loongarch32, .loongarch64 => .loongarch,
1447 .m68k => .m68k,
1448 .mips, .mipsel, .mips64, .mips64el => .mips,
1449 .msp430 => .msp430,
1450 .or1k => .or1k,
1451 .nvptx, .nvptx64 => .nvptx,
1452 .powerpc, .powerpcle, .powerpc64, .powerpc64le => .powerpc,
1453 .propeller => .propeller,
1454 .riscv32, .riscv64 => .riscv,
1455 .s390x => .s390x,
1456 .sparc, .sparc64 => .sparc,
1457 .spirv, .spirv32, .spirv64 => .spirv,
1458 .ve => .ve,
1459 .wasm32, .wasm64 => .wasm,
1460 .x86, .x86_64 => .x86,
1461 .xcore => .xcore,
1462 .xtensa => .xtensa,
1463 };
1464 }
1465
13991466 pub inline fn isX86(arch: Arch) bool {
14001467 return switch (arch) {
14011468 .x86, .x86_64 => true,
......@@ -1574,88 +1641,17 @@ pub const Cpu = struct {
15741641 };
15751642 }
15761643
1577 /// Returns a name that matches the lib/std/target/* source file name.
1578 pub fn genericName(arch: Arch) [:0]const u8 {
1579 return switch (arch) {
1580 .arm, .armeb, .thumb, .thumbeb => "arm",
1581 .aarch64, .aarch64_be => "aarch64",
1582 .bpfel, .bpfeb => "bpf",
1583 .loongarch32, .loongarch64 => "loongarch",
1584 .mips, .mipsel, .mips64, .mips64el => "mips",
1585 .powerpc, .powerpcle, .powerpc64, .powerpc64le => "powerpc",
1586 .propeller => "propeller",
1587 .riscv32, .riscv64 => "riscv",
1588 .sparc, .sparc64 => "sparc",
1589 .s390x => "s390x",
1590 .x86, .x86_64 => "x86",
1591 .nvptx, .nvptx64 => "nvptx",
1592 .wasm32, .wasm64 => "wasm",
1593 .spirv, .spirv32, .spirv64 => "spirv",
1594 else => @tagName(arch),
1595 };
1596 }
1597
15981644 /// All CPU features Zig is aware of, sorted lexicographically by name.
15991645 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
1600 return switch (arch) {
1601 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
1602 .aarch64, .aarch64_be => &aarch64.all_features,
1603 .arc => &arc.all_features,
1604 .avr => &avr.all_features,
1605 .bpfel, .bpfeb => &bpf.all_features,
1606 .csky => &csky.all_features,
1607 .hexagon => &hexagon.all_features,
1608 .lanai => &lanai.all_features,
1609 .loongarch32, .loongarch64 => &loongarch.all_features,
1610 .m68k => &m68k.all_features,
1611 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
1612 .msp430 => &msp430.all_features,
1613 .powerpc, .powerpcle, .powerpc64, .powerpc64le => &powerpc.all_features,
1614 .amdgcn => &amdgcn.all_features,
1615 .riscv32, .riscv64 => &riscv.all_features,
1616 .sparc, .sparc64 => &sparc.all_features,
1617 .spirv, .spirv32, .spirv64 => &spirv.all_features,
1618 .s390x => &s390x.all_features,
1619 .x86, .x86_64 => &x86.all_features,
1620 .xcore => &xcore.all_features,
1621 .xtensa => &xtensa.all_features,
1622 .nvptx, .nvptx64 => &nvptx.all_features,
1623 .ve => &ve.all_features,
1624 .wasm32, .wasm64 => &wasm.all_features,
1625
1626 else => &[0]Cpu.Feature{},
1646 return switch (arch.family()) {
1647 inline else => |f| &@field(Target, @tagName(f)).all_features,
16271648 };
16281649 }
16291650
16301651 /// All processors Zig is aware of, sorted lexicographically by name.
16311652 pub fn allCpuModels(arch: Arch) []const *const Cpu.Model {
1632 return switch (arch) {
1633 .arc => comptime allCpusFromDecls(arc.cpu),
1634 .arm, .armeb, .thumb, .thumbeb => comptime allCpusFromDecls(arm.cpu),
1635 .aarch64, .aarch64_be => comptime allCpusFromDecls(aarch64.cpu),
1636 .avr => comptime allCpusFromDecls(avr.cpu),
1637 .bpfel, .bpfeb => comptime allCpusFromDecls(bpf.cpu),
1638 .csky => comptime allCpusFromDecls(csky.cpu),
1639 .hexagon => comptime allCpusFromDecls(hexagon.cpu),
1640 .lanai => comptime allCpusFromDecls(lanai.cpu),
1641 .loongarch32, .loongarch64 => comptime allCpusFromDecls(loongarch.cpu),
1642 .m68k => comptime allCpusFromDecls(m68k.cpu),
1643 .mips, .mipsel, .mips64, .mips64el => comptime allCpusFromDecls(mips.cpu),
1644 .msp430 => comptime allCpusFromDecls(msp430.cpu),
1645 .powerpc, .powerpcle, .powerpc64, .powerpc64le => comptime allCpusFromDecls(powerpc.cpu),
1646 .amdgcn => comptime allCpusFromDecls(amdgcn.cpu),
1647 .riscv32, .riscv64 => comptime allCpusFromDecls(riscv.cpu),
1648 .sparc, .sparc64 => comptime allCpusFromDecls(sparc.cpu),
1649 .spirv, .spirv32, .spirv64 => comptime allCpusFromDecls(spirv.cpu),
1650 .s390x => comptime allCpusFromDecls(s390x.cpu),
1651 .x86, .x86_64 => comptime allCpusFromDecls(x86.cpu),
1652 .xcore => comptime allCpusFromDecls(xcore.cpu),
1653 .xtensa => comptime allCpusFromDecls(xtensa.cpu),
1654 .nvptx, .nvptx64 => comptime allCpusFromDecls(nvptx.cpu),
1655 .ve => comptime allCpusFromDecls(ve.cpu),
1656 .wasm32, .wasm64 => comptime allCpusFromDecls(wasm.cpu),
1657
1658 else => &[0]*const Model{},
1653 return switch (arch.family()) {
1654 inline else => |f| comptime allCpusFromDecls(@field(Target, @tagName(f)).cpu),
16591655 };
16601656 }
16611657
......@@ -1871,49 +1867,24 @@ pub const Cpu = struct {
18711867 /// can return CPU models that are understood by LLVM, but *not* understood by Clang. If
18721868 /// Clang compatibility is important, consider using `baseline` instead.
18731869 pub fn generic(arch: Arch) *const Model {
1874 const S = struct {
1875 const generic_model = Model{
1876 .name = "generic",
1877 .llvm_name = null,
1878 .features = Cpu.Feature.Set.empty,
1879 };
1880 };
18811870 return switch (arch) {
18821871 .amdgcn => &amdgcn.cpu.gfx600,
1883 .arc => &arc.cpu.generic,
1884 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
1885 .aarch64, .aarch64_be => &aarch64.cpu.generic,
18861872 .avr => &avr.cpu.avr1,
1887 .bpfel, .bpfeb => &bpf.cpu.generic,
1888 .csky => &csky.cpu.generic,
1889 .hexagon => &hexagon.cpu.generic,
1890 .lanai => &lanai.cpu.generic,
18911873 .loongarch32 => &loongarch.cpu.generic_la32,
18921874 .loongarch64 => &loongarch.cpu.generic_la64,
1893 .m68k => &m68k.cpu.generic,
18941875 .mips, .mipsel => &mips.cpu.mips32,
18951876 .mips64, .mips64el => &mips.cpu.mips64,
1896 .msp430 => &msp430.cpu.generic,
1877 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
18971878 .powerpc, .powerpcle => &powerpc.cpu.ppc,
18981879 .powerpc64, .powerpc64le => &powerpc.cpu.ppc64,
18991880 .propeller => &propeller.cpu.p1,
19001881 .riscv32 => &riscv.cpu.generic_rv32,
19011882 .riscv64 => &riscv.cpu.generic_rv64,
1902 .spirv, .spirv32, .spirv64 => &spirv.cpu.generic,
1903 .sparc => &sparc.cpu.generic,
1904 .sparc64 => &sparc.cpu.v9, // 64-bit SPARC needs v9 as the baseline
1905 .s390x => &s390x.cpu.generic,
1883 .sparc64 => &sparc.cpu.v9, // SPARC can only be 64-bit from v9 and up.
1884 .wasm32, .wasm64 => &wasm.cpu.mvp,
19061885 .x86 => &x86.cpu.i386,
19071886 .x86_64 => &x86.cpu.x86_64,
1908 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
1909 .ve => &ve.cpu.generic,
1910 .wasm32, .wasm64 => &wasm.cpu.mvp,
1911 .xcore => &xcore.cpu.generic,
1912 .xtensa => &xtensa.cpu.generic,
1913
1914 .kalimba,
1915 .or1k,
1916 => &S.generic_model,
1887 inline else => |a| &@field(Target, @tagName(a.family())).cpu.generic,
19171888 };
19181889 }
19191890
......@@ -1994,7 +1965,7 @@ pub const Cpu = struct {
19941965 .fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer),
19951966 .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, // TODO this should also check how many flash banks the cpu has
19961967 .cog, .hub => arch == .propeller,
1997 .lut => arch == .propeller and std.Target.propeller.featureSetHas(cpu.features, .p2),
1968 .lut => arch == .propeller and cpu.has(.propeller, .p2),
19981969
19991970 .global, .local, .shared => is_gpu,
20001971 .constant => is_gpu and (context == null or context == .constant),
......@@ -2002,6 +1973,30 @@ pub const Cpu = struct {
20021973 .input, .output, .uniform, .push_constant, .storage_buffer, .physical_storage_buffer => is_spirv,
20031974 };
20041975 }
1976
1977 /// Returns true if `feature` is enabled.
1978 pub fn has(cpu: Cpu, comptime family: Arch.Family, feature: @field(Target, @tagName(family)).Feature) bool {
1979 if (family != cpu.arch.family()) return false;
1980 return cpu.features.isEnabled(@intFromEnum(feature));
1981 }
1982
1983 /// Returns true if any feature in `features` is enabled.
1984 pub fn hasAny(cpu: Cpu, comptime family: Arch.Family, features: []const @field(Target, @tagName(family)).Feature) bool {
1985 if (family != cpu.arch.family()) return false;
1986 for (features) |feature| {
1987 if (cpu.features.isEnabled(@intFromEnum(feature))) return true;
1988 }
1989 return false;
1990 }
1991
1992 /// Returns true if all features in `features` are enabled.
1993 pub fn hasAll(cpu: Cpu, comptime family: Arch.Family, features: []const @field(Target, @tagName(family)).Feature) bool {
1994 if (family != cpu.arch.family()) return false;
1995 for (features) |feature| {
1996 if (!cpu.features.isEnabled(@intFromEnum(feature))) return false;
1997 }
1998 return true;
1999 }
20052000};
20062001
20072002pub fn zigTriple(target: Target, allocator: Allocator) Allocator.Error![]u8 {
......@@ -2295,7 +2290,7 @@ pub const DynamicLinker = struct {
22952290 .mips,
22962291 .mipsel,
22972292 => |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}.so.1", .{
2298 if (mips.featureSetHas(cpu.features, .mips32r6)) "r6" else "",
2293 if (cpu.has(.mips, .mips32r6)) "r6" else "",
22992294 if (arch == .mipsel) "el" else "",
23002295 switch (abi) {
23012296 .musleabi => "-sf",
......@@ -2312,7 +2307,7 @@ pub const DynamicLinker = struct {
23122307 .muslabin32 => "n32",
23132308 else => return none,
23142309 },
2315 if (mips.featureSetHas(cpu.features, .mips64r6)) "r6" else "",
2310 if (cpu.has(.mips, .mips64r6)) "r6" else "",
23162311 if (arch == .mips64el) "el" else "",
23172312 }),
23182313
......@@ -2326,9 +2321,9 @@ pub const DynamicLinker = struct {
23262321 .riscv64,
23272322 => |arch| if (abi == .musl) initFmt("/lib/ld-musl-{s}{s}.so.1", .{
23282323 @tagName(arch),
2329 if (riscv.featureSetHas(cpu.features, .d))
2324 if (cpu.has(.riscv, .d))
23302325 ""
2331 else if (riscv.featureSetHas(cpu.features, .f))
2326 else if (cpu.has(.riscv, .f))
23322327 "-sp"
23332328 else
23342329 "-sf",
......@@ -2385,7 +2380,7 @@ pub const DynamicLinker = struct {
23852380 .gnueabi,
23862381 .gnueabihf,
23872382 => initFmt("/lib/ld{s}.so.1", .{
2388 if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
2383 if (cpu.has(.mips, .nan2008)) "-linux-mipsn8" else "",
23892384 }),
23902385 else => none,
23912386 },
......@@ -2398,7 +2393,7 @@ pub const DynamicLinker = struct {
23982393 .gnuabin32 => "32",
23992394 else => return none,
24002395 },
2401 if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "",
2396 if (cpu.has(.mips, .nan2008)) "-linux-mipsn8" else "",
24022397 }),
24032398
24042399 .powerpc => switch (abi) {
......@@ -2419,9 +2414,9 @@ pub const DynamicLinker = struct {
24192414 .riscv64 => "riscv64-lp64",
24202415 else => unreachable,
24212416 },
2422 if (riscv.featureSetHas(cpu.features, .d))
2417 if (cpu.has(.riscv, .d))
24232418 "d"
2424 else if (riscv.featureSetHas(cpu.features, .f))
2419 else if (cpu.has(.riscv, .f))
24252420 "f"
24262421 else
24272422 "",
......@@ -2686,7 +2681,7 @@ pub fn stackAlignment(target: Target) u16 {
26862681 => if (target.os.tag == .linux or target.os.tag == .aix) return 16,
26872682 .riscv32,
26882683 .riscv64,
2689 => if (!Target.riscv.featureSetHas(target.cpu.features, .e)) return 16,
2684 => if (!target.cpu.has(.riscv, .e)) return 16,
26902685 .x86 => if (target.os.tag != .windows and target.os.tag != .uefi) return 16,
26912686 .x86_64 => return 16,
26922687 else => {},
......@@ -3398,6 +3393,7 @@ const Target = @This();
33983393const std = @import("std.zig");
33993394const builtin = @import("builtin");
34003395const Allocator = std.mem.Allocator;
3396const assert = std.debug.assert;
34013397
34023398test {
34033399 std.testing.refAllDecls(Cpu.Arch);
lib/std/Target/Query.zig+10-10
......@@ -653,16 +653,16 @@ test parse {
653653 try std.testing.expect(target.os.tag == .linux);
654654 try std.testing.expect(target.abi == .gnu);
655655 try std.testing.expect(target.cpu.arch == .x86_64);
656 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
657 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
658 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
659 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
660 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
656 try std.testing.expect(!target.cpu.has(.x86, .sse));
657 try std.testing.expect(!target.cpu.has(.x86, .avx));
658 try std.testing.expect(!target.cpu.has(.x86, .cx8));
659 try std.testing.expect(target.cpu.has(.x86, .cmov));
660 try std.testing.expect(target.cpu.has(.x86, .fxsr));
661661
662 try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
663 try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
664 try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
665 try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
662 try std.testing.expect(target.cpu.hasAny(.x86, &.{ .sse, .avx, .cmov }));
663 try std.testing.expect(!target.cpu.hasAny(.x86, &.{ .sse, .avx }));
664 try std.testing.expect(target.cpu.hasAll(.x86, &.{ .mmx, .x87 }));
665 try std.testing.expect(!target.cpu.hasAll(.x86, &.{ .mmx, .x87, .sse }));
666666
667667 const text = try query.zigTriple(std.testing.allocator);
668668 defer std.testing.allocator.free(text);
......@@ -679,7 +679,7 @@ test parse {
679679 try std.testing.expect(target.abi == .musleabihf);
680680 try std.testing.expect(target.cpu.arch == .arm);
681681 try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
682 try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
682 try std.testing.expect(target.cpu.has(.arm, .v8a));
683683
684684 const text = try query.zigTriple(std.testing.allocator);
685685 defer std.testing.allocator.free(text);
lib/std/Target/generic.zig created+20
......@@ -0,0 +1,20 @@
1const std = @import("../std.zig");
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
4
5pub const Feature = enum {};
6
7pub const featureSet = CpuFeature.FeatureSetFns(Feature).featureSet;
8pub const featureSetHas = CpuFeature.FeatureSetFns(Feature).featureSetHas;
9pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny;
10pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll;
11
12pub const all_features: [0]CpuFeature = .{};
13
14pub const cpu = struct {
15 pub const generic: CpuModel = .{
16 .name = "generic",
17 .llvm_name = null,
18 .features = featureSet(&.{}),
19 };
20};
lib/std/Thread/Futex.zig+4-6
......@@ -461,9 +461,8 @@ const DragonflyImpl = struct {
461461
462462const WasmImpl = struct {
463463 fn wait(ptr: *const atomic.Value(u32), expect: u32, timeout: ?u64) error{Timeout}!void {
464 if (!comptime std.Target.wasm.featureSetHas(builtin.target.cpu.features, .atomics)) {
465 @compileError("WASI target missing cpu feature 'atomics'");
466 }
464 if (!comptime builtin.cpu.has(.wasm, .atomics)) @compileError("WASI target missing cpu feature 'atomics'");
465
467466 const to: i64 = if (timeout) |to| @intCast(to) else -1;
468467 const result = asm volatile (
469468 \\local.get %[ptr]
......@@ -485,9 +484,8 @@ const WasmImpl = struct {
485484 }
486485
487486 fn wake(ptr: *const atomic.Value(u32), max_waiters: u32) void {
488 if (!comptime std.Target.wasm.featureSetHas(builtin.target.cpu.features, .atomics)) {
489 @compileError("WASI target missing cpu feature 'atomics'");
490 }
487 if (!comptime builtin.cpu.has(.wasm, .atomics)) @compileError("WASI target missing cpu feature 'atomics'");
488
491489 assert(max_waiters != 0);
492490 const woken_count = asm volatile (
493491 \\local.get %[ptr]
lib/std/atomic.zig+4-9
......@@ -378,13 +378,8 @@ pub inline fn spinLoopHint() void {
378378 .armeb,
379379 .thumb,
380380 .thumbeb,
381 => {
382 const can_yield = comptime std.Target.arm.featureSetHasAny(builtin.target.cpu.features, .{
383 .has_v6k, .has_v6m,
384 });
385 if (can_yield) {
386 asm volatile ("yield");
387 }
381 => if (comptime builtin.cpu.hasAny(.arm, &.{ .has_v6k, .has_v6m })) {
382 asm volatile ("yield");
388383 },
389384
390385 // The 8-bit immediate specifies the amount of cycles to pause for. We can't really be too
......@@ -394,7 +389,7 @@ pub inline fn spinLoopHint() void {
394389
395390 .riscv32,
396391 .riscv64,
397 => if (comptime std.Target.riscv.featureSetHas(builtin.target.cpu.features, .zihintpause)) {
392 => if (comptime builtin.cpu.has(.riscv, .zihintpause)) {
398393 asm volatile ("pause");
399394 },
400395
......@@ -430,7 +425,7 @@ pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 {
430425
431426 // https://github.com/llvm/llvm-project/blob/e379094328e49731a606304f7e3559d4f1fa96f9/clang/lib/Basic/Targets/Hexagon.h#L145-L151
432427 .hexagon,
433 => if (std.Target.hexagon.featureSetHas(cpu.features, .v73)) 64 else 32,
428 => if (cpu.has(.hexagon, .v73)) 64 else 32,
434429
435430 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7
436431 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7
lib/std/crypto/aes.zig+3-3
......@@ -2,9 +2,9 @@ const std = @import("../std.zig");
22const builtin = @import("builtin");
33const testing = std.testing;
44
5const has_aesni = std.Target.x86.featureSetHas(builtin.cpu.features, .aes);
6const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
7const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
5const has_aesni = builtin.cpu.has(.x86, .aes);
6const has_avx = builtin.cpu.has(.x86, .avx);
7const has_armaes = builtin.cpu.has(.aarch64, .aes);
88// C backend doesn't currently support passing vectors to inline asm.
99const impl = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_aesni and has_avx) impl: {
1010 break :impl @import("aes/aesni.zig");
lib/std/crypto/aes/aesni.zig+2-2
......@@ -3,8 +3,8 @@ const builtin = @import("builtin");
33const mem = std.mem;
44const debug = std.debug;
55
6const has_vaes = builtin.cpu.arch == .x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .vaes);
7const has_avx512f = builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f);
6const has_vaes = builtin.cpu.arch == .x86_64 and builtin.cpu.has(.x86, .vaes);
7const has_avx512f = builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_x86_64 and builtin.cpu.has(.x86, .avx512f);
88
99/// A single AES block.
1010pub const Block = struct {
lib/std/crypto/aes_ocb.zig+2-2
......@@ -101,8 +101,8 @@ fn AesOcb(comptime Aes: anytype) type {
101101 return offset;
102102 }
103103
104 const has_aesni = std.Target.x86.featureSetHas(builtin.cpu.features, .aes);
105 const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
104 const has_aesni = builtin.cpu.has(.x86, .aes);
105 const has_armaes = builtin.cpu.has(.aarch64, .aes);
106106 const wb: usize = if ((builtin.cpu.arch == .x86_64 and has_aesni) or (builtin.cpu.arch == .aarch64 and has_armaes)) 4 else 0;
107107
108108 /// c: ciphertext: output buffer should be of size m.len
lib/std/crypto/chacha20.zig+3-3
......@@ -499,12 +499,12 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type {
499499fn ChaChaImpl(comptime rounds_nb: usize) type {
500500 switch (builtin.cpu.arch) {
501501 .x86_64 => {
502 if (builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f)) return ChaChaVecImpl(rounds_nb, 4);
503 if (std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return ChaChaVecImpl(rounds_nb, 2);
502 if (builtin.zig_backend != .stage2_x86_64 and builtin.cpu.has(.x86, .avx512f)) return ChaChaVecImpl(rounds_nb, 4);
503 if (builtin.cpu.has(.x86, .avx2)) return ChaChaVecImpl(rounds_nb, 2);
504504 return ChaChaVecImpl(rounds_nb, 1);
505505 },
506506 .aarch64 => {
507 if (builtin.zig_backend != .stage2_aarch64 and std.Target.aarch64.featureSetHas(builtin.cpu.features, .neon)) return ChaChaVecImpl(rounds_nb, 4);
507 if (builtin.zig_backend != .stage2_aarch64 and builtin.cpu.has(.aarch64, .neon)) return ChaChaVecImpl(rounds_nb, 4);
508508 return ChaChaNonVecImpl(rounds_nb);
509509 },
510510 else => return ChaChaNonVecImpl(rounds_nb),
lib/std/crypto/ghash_polyval.zig+3-3
......@@ -284,9 +284,9 @@ fn Hash(comptime endian: std.builtin.Endian, comptime shift_key: bool) type {
284284 return d ^ hi;
285285 }
286286
287 const has_pclmul = std.Target.x86.featureSetHas(builtin.cpu.features, .pclmul);
288 const has_avx = std.Target.x86.featureSetHas(builtin.cpu.features, .avx);
289 const has_armaes = std.Target.aarch64.featureSetHas(builtin.cpu.features, .aes);
287 const has_pclmul = builtin.cpu.has(.x86, .pclmul);
288 const has_avx = builtin.cpu.has(.x86, .avx);
289 const has_armaes = builtin.cpu.has(.aarch64, .aes);
290290 // C backend doesn't currently support passing vectors to inline asm.
291291 const clmul = if (builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_c and has_pclmul and has_avx) impl: {
292292 break :impl clmulPclmul;
lib/std/crypto/sha2.zig+2-2
......@@ -200,7 +200,7 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type {
200200 if (!@inComptime()) {
201201 const V4u32 = @Vector(4, u32);
202202 switch (builtin.cpu.arch) {
203 .aarch64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.aarch64.featureSetHas(builtin.cpu.features, .sha2)) {
203 .aarch64 => if (builtin.zig_backend != .stage2_c and comptime builtin.cpu.has(.aarch64, .sha2)) {
204204 var x: V4u32 = d.s[0..4].*;
205205 var y: V4u32 = d.s[4..8].*;
206206 const s_v = @as(*[16]V4u32, @ptrCast(&s));
......@@ -238,7 +238,7 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type {
238238 return;
239239 },
240240 // C backend doesn't currently support passing vectors to inline asm.
241 .x86_64 => if (builtin.zig_backend != .stage2_c and comptime std.Target.x86.featureSetHasAll(builtin.cpu.features, .{ .sha, .avx2 })) {
241 .x86_64 => if (builtin.zig_backend != .stage2_c and comptime builtin.cpu.hasAll(.x86, &.{ .sha, .avx2 })) {
242242 var x: V4u32 = [_]u32{ d.s[5], d.s[4], d.s[1], d.s[0] };
243243 var y: V4u32 = [_]u32{ d.s[7], d.s[6], d.s[3], d.s[2] };
244244 const s_v = @as(*[16]V4u32, @ptrCast(&s));
lib/std/debug.zig+1-1
......@@ -773,7 +773,7 @@ pub const StackIterator = struct {
773773 pub fn init(first_address: ?usize, fp: ?usize) StackIterator {
774774 if (native_arch.isSPARC()) {
775775 // Flush all the register windows on stack.
776 asm volatile (if (std.Target.sparc.featureSetHas(builtin.cpu.features, .v9))
776 asm volatile (if (builtin.cpu.has(.sparc, .v9))
777777 "flushw"
778778 else
779779 "ta 3" // ST_FLUSH_WINDOWS
lib/std/math.zig+1-2
......@@ -1365,8 +1365,7 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
13651365
13661366test lerp {
13671367 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
1368 if (builtin.zig_backend == .stage2_x86_64 and
1369 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
1368 if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
13701369
13711370 try testing.expectEqual(@as(f64, 75), lerp(50, 100, 0.5));
13721371 try testing.expectEqual(@as(f32, 43.75), lerp(50, 25, 0.25));
lib/std/simd.zig+31-40
......@@ -13,68 +13,59 @@ pub fn suggestVectorLengthForCpu(comptime T: type, comptime cpu: std.Target.Cpu)
1313 const element_bit_size = @max(8, std.math.ceilPowerOfTwo(u16, @bitSizeOf(T)) catch unreachable);
1414 const vector_bit_size: u16 = blk: {
1515 if (cpu.arch.isX86()) {
16 if (T == bool and std.Target.x86.featureSetHas(cpu.features, .prefer_mask_registers)) return 64;
17 if (builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(cpu.features, .avx512f) and !std.Target.x86.featureSetHasAny(cpu.features, .{ .prefer_256_bit, .prefer_128_bit })) break :blk 512;
18 if (std.Target.x86.featureSetHasAny(cpu.features, .{ .prefer_256_bit, .avx2 }) and !std.Target.x86.featureSetHas(cpu.features, .prefer_128_bit)) break :blk 256;
19 if (std.Target.x86.featureSetHas(cpu.features, .sse)) break :blk 128;
20 if (std.Target.x86.featureSetHasAny(cpu.features, .{ .mmx, .@"3dnow" })) break :blk 64;
16 if (T == bool and cpu.has(.x86, .prefer_mask_registers)) return 64;
17 if (builtin.zig_backend != .stage2_x86_64 and cpu.has(.x86, .avx512f) and !cpu.hasAny(.x86, &.{ .prefer_256_bit, .prefer_128_bit })) break :blk 512;
18 if (cpu.hasAny(.x86, &.{ .prefer_256_bit, .avx2 }) and !cpu.has(.x86, .prefer_128_bit)) break :blk 256;
19 if (cpu.has(.x86, .sse)) break :blk 128;
20 if (cpu.hasAny(.x86, &.{ .mmx, .@"3dnow" })) break :blk 64;
2121 } else if (cpu.arch.isArm()) {
22 if (std.Target.arm.featureSetHas(cpu.features, .neon)) break :blk 128;
22 if (cpu.has(.arm, .neon)) break :blk 128;
2323 } else if (cpu.arch.isAARCH64()) {
2424 // SVE allows up to 2048 bits in the specification, as of 2022 the most powerful machine has implemented 512-bit
2525 // I think is safer to just be on 128 until is more common
2626 // TODO: Check on this return when bigger values are more common
27 if (std.Target.aarch64.featureSetHas(cpu.features, .sve)) break :blk 128;
28 if (std.Target.aarch64.featureSetHas(cpu.features, .neon)) break :blk 128;
27 if (cpu.has(.aarch64, .sve)) break :blk 128;
28 if (cpu.has(.aarch64, .neon)) break :blk 128;
2929 } else if (cpu.arch.isPowerPC()) {
30 if (std.Target.powerpc.featureSetHas(cpu.features, .altivec)) break :blk 128;
30 if (cpu.has(.powerpc, .altivec)) break :blk 128;
3131 } else if (cpu.arch.isMIPS()) {
32 if (std.Target.mips.featureSetHas(cpu.features, .msa)) break :blk 128;
32 if (cpu.has(.mips, .msa)) break :blk 128;
3333 // TODO: Test MIPS capability to handle bigger vectors
3434 // In theory MDMX and by extension mips3d have 32 registers of 64 bits which can use in parallel
3535 // for multiple processing, but I don't know what's optimal here, if using
3636 // the 2048 bits or using just 64 per vector or something in between
37 if (std.Target.mips.featureSetHas(cpu.features, std.Target.mips.Feature.mips3d)) break :blk 64;
37 if (cpu.has(.mips, .mips3d)) break :blk 64;
3838 } else if (cpu.arch.isRISCV()) {
3939 // In RISC-V Vector Registers are length agnostic so there's no good way to determine the best size.
4040 // The usual vector length in most RISC-V cpus is 256 bits, however it can get to multiple kB.
41 if (std.Target.riscv.featureSetHas(cpu.features, .v)) {
42 var vec_bit_length: u32 = 256;
43 if (std.Target.riscv.featureSetHas(cpu.features, .zvl32b)) {
44 vec_bit_length = 32;
45 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl64b)) {
46 vec_bit_length = 64;
47 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl128b)) {
48 vec_bit_length = 128;
49 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl256b)) {
50 vec_bit_length = 256;
51 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl512b)) {
52 vec_bit_length = 512;
53 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl1024b)) {
54 vec_bit_length = 1024;
55 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl2048b)) {
56 vec_bit_length = 2048;
57 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl4096b)) {
58 vec_bit_length = 4096;
59 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl8192b)) {
60 vec_bit_length = 8192;
61 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl16384b)) {
62 vec_bit_length = 16384;
63 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl32768b)) {
64 vec_bit_length = 32768;
65 } else if (std.Target.riscv.featureSetHas(cpu.features, .zvl65536b)) {
66 vec_bit_length = 65536;
41 if (cpu.has(.riscv, .v)) {
42 inline for (.{
43 .{ .zvl65536b, 65536 },
44 .{ .zvl32768b, 32768 },
45 .{ .zvl16384b, 16384 },
46 .{ .zvl8192b, 8192 },
47 .{ .zvl4096b, 4096 },
48 .{ .zvl2048b, 2048 },
49 .{ .zvl1024b, 1024 },
50 .{ .zvl512b, 512 },
51 .{ .zvl256b, 256 },
52 .{ .zvl128b, 128 },
53 .{ .zvl64b, 64 },
54 .{ .zvl32b, 32 },
55 }) |mapping| {
56 if (cpu.has(.riscv, mapping[0])) break :blk mapping[1];
6757 }
68 break :blk vec_bit_length;
58
59 break :blk 256;
6960 }
7061 } else if (cpu.arch.isSPARC()) {
7162 // TODO: Test Sparc capability to handle bigger vectors
7263 // In theory Sparc have 32 registers of 64 bits which can use in parallel
7364 // for multiple processing, but I don't know what's optimal here, if using
7465 // the 2048 bits or using just 64 per vector or something in between
75 if (std.Target.sparc.featureSetHasAny(cpu.features, .{ .vis, .vis2, .vis3 })) break :blk 64;
66 if (cpu.hasAny(.sparc, &.{ .vis, .vis2, .vis3 })) break :blk 64;
7667 } else if (cpu.arch.isWasm()) {
77 if (std.Target.wasm.featureSetHas(cpu.features, .simd128)) break :blk 128;
68 if (cpu.has(.wasm, .simd128)) break :blk 128;
7869 }
7970 return null;
8071 };
lib/std/zig/system.zig+1-1
......@@ -109,7 +109,7 @@ pub fn getExternalExecutor(
109109 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
110110 .s390x => Executor{ .qemu = "qemu-s390x" },
111111 .sparc => Executor{
112 .qemu = if (std.Target.sparc.featureSetHas(candidate.cpu.features, .v9))
112 .qemu = if (candidate.cpu.has(.sparc, .v9))
113113 "qemu-sparc32plus"
114114 else
115115 "qemu-sparc",
lib/std/zig/system/x86.zig+9-9
......@@ -77,7 +77,7 @@ pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, query: T
7777 detectIntelProcessor(&cpu, family, model, brand_id);
7878 },
7979 0x68747541 => {
80 if (detectAMDProcessor(cpu.features, family, model)) |m| cpu.model = m;
80 if (detectAMDProcessor(cpu, family, model)) |m| cpu.model = m;
8181 },
8282 else => {},
8383 }
......@@ -107,7 +107,7 @@ fn detectIntelProcessor(cpu: *Target.Cpu, family: u32, model: u32, brand_id: u32
107107 return;
108108 },
109109 5 => {
110 if (Target.x86.featureSetHas(cpu.features, .mmx)) {
110 if (cpu.has(.x86, .mmx)) {
111111 cpu.model = &Target.x86.cpu.pentium_mmx;
112112 return;
113113 }
......@@ -177,10 +177,10 @@ fn detectIntelProcessor(cpu: *Target.Cpu, family: u32, model: u32, brand_id: u32
177177 return;
178178 },
179179 0x55 => {
180 if (Target.x86.featureSetHas(cpu.features, .avx512bf16)) {
180 if (cpu.has(.x86, .avx512bf16)) {
181181 cpu.model = &Target.x86.cpu.cooperlake;
182182 return;
183 } else if (Target.x86.featureSetHas(cpu.features, .avx512vnni)) {
183 } else if (cpu.has(.x86, .avx512vnni)) {
184184 cpu.model = &Target.x86.cpu.cascadelake;
185185 return;
186186 } else {
......@@ -296,11 +296,11 @@ fn detectIntelProcessor(cpu: *Target.Cpu, family: u32, model: u32, brand_id: u32
296296 }
297297 },
298298 15 => {
299 if (Target.x86.featureSetHas(cpu.features, .@"64bit")) {
299 if (cpu.has(.x86, .@"64bit")) {
300300 cpu.model = &Target.x86.cpu.nocona;
301301 return;
302302 }
303 if (Target.x86.featureSetHas(cpu.features, .sse3)) {
303 if (cpu.has(.x86, .sse3)) {
304304 cpu.model = &Target.x86.cpu.prescott;
305305 return;
306306 }
......@@ -311,7 +311,7 @@ fn detectIntelProcessor(cpu: *Target.Cpu, family: u32, model: u32, brand_id: u32
311311 }
312312}
313313
314fn detectAMDProcessor(features: Target.Cpu.Feature.Set, family: u32, model: u32) ?*const Target.Cpu.Model {
314fn detectAMDProcessor(cpu: Target.Cpu, family: u32, model: u32) ?*const Target.Cpu.Model {
315315 return switch (family) {
316316 4 => &Target.x86.cpu.i486,
317317 5 => switch (model) {
......@@ -321,11 +321,11 @@ fn detectAMDProcessor(features: Target.Cpu.Feature.Set, family: u32, model: u32)
321321 10 => &Target.x86.cpu.geode,
322322 else => &Target.x86.cpu.pentium,
323323 },
324 6 => if (Target.x86.featureSetHas(features, .sse))
324 6 => if (cpu.has(.x86, .sse))
325325 &Target.x86.cpu.athlon_xp
326326 else
327327 &Target.x86.cpu.athlon,
328 15 => if (Target.x86.featureSetHas(features, .sse3))
328 15 => if (cpu.has(.x86, .sse3))
329329 &Target.x86.cpu.k8_sse3
330330 else
331331 &Target.x86.cpu.k8,
src/Builtin.zig+3-3
......@@ -47,7 +47,7 @@ pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 {
4747
4848pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
4949 const target = opts.target;
50 const generic_arch_name = target.cpu.arch.genericName();
50 const arch_family_name = @tagName(target.cpu.arch.family());
5151 const zig_backend = opts.zig_backend;
5252
5353 @setEvalBranchQuota(4000);
......@@ -80,9 +80,9 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
8080 opts.single_threaded,
8181 std.zig.fmtId(@tagName(target.abi)),
8282 std.zig.fmtId(@tagName(target.cpu.arch)),
83 std.zig.fmtId(generic_arch_name),
83 std.zig.fmtId(arch_family_name),
8484 std.zig.fmtId(target.cpu.model.name),
85 std.zig.fmtId(generic_arch_name),
85 std.zig.fmtId(arch_family_name),
8686 });
8787
8888 for (target.cpu.arch.allFeaturesList(), 0..) |feature, index_usize| {
src/Compilation.zig+4-4
......@@ -6469,7 +6469,7 @@ pub fn addCCArgs(
64696469 var march_index: usize = prefix_len;
64706470 @memcpy(march_buf[0..prefix.len], prefix);
64716471
6472 if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) {
6472 if (target.cpu.has(.riscv, .e)) {
64736473 march_buf[march_index] = 'e';
64746474 } else {
64756475 march_buf[march_index] = 'i';
......@@ -6477,7 +6477,7 @@ pub fn addCCArgs(
64776477 march_index += 1;
64786478
64796479 for (letters) |letter| {
6480 if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) {
6480 if (target.cpu.has(.riscv, letter.feat)) {
64816481 march_buf[march_index] = letter.char;
64826482 march_index += 1;
64836483 }
......@@ -6488,12 +6488,12 @@ pub fn addCCArgs(
64886488 });
64896489 try argv.append(march_arg);
64906490
6491 if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) {
6491 if (target.cpu.has(.riscv, .relax)) {
64926492 try argv.append("-mrelax");
64936493 } else {
64946494 try argv.append("-mno-relax");
64956495 }
6496 if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) {
6496 if (target.cpu.has(.riscv, .save_restore)) {
64976497 try argv.append("-msave-restore");
64986498 } else {
64996499 try argv.append("-mno-save-restore");
src/Compilation/Config.zig+1-1
......@@ -166,7 +166,7 @@ pub fn resolve(options: Options) ResolveError!Config {
166166 if (options.shared_memory == true) return error.ObjectFilesCannotShareMemory;
167167 break :b false;
168168 }
169 if (!std.Target.wasm.featureSetHasAll(target.cpu.features, .{ .atomics, .bulk_memory })) {
169 if (!target.cpu.hasAll(.wasm, &.{ .atomics, .bulk_memory })) {
170170 if (options.shared_memory == true)
171171 return error.SharedMemoryRequiresAtomicsAndBulkMemory;
172172 break :b false;
src/Sema.zig+3-3
......@@ -9594,7 +9594,7 @@ fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type)
95949594 const backend = target_util.zigBackend(target, zcu.comp.config.use_llvm);
95959595 try sema.errNote(src, msg, "pointers with address space '{s}' cannot be returned from a branch on target {s}-{s} by compiler backend {s}", .{
95969596 @tagName(as),
9597 target.cpu.arch.genericName(),
9597 @tagName(target.cpu.arch.family()),
95989598 @tagName(target.os.tag),
95999599 @tagName(backend),
96009600 });
......@@ -23604,7 +23604,7 @@ fn checkLogicalPtrOperation(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
2360423604 "cannot perform arithmetic on pointers with address space '{s}' on target {s}-{s}",
2360523605 .{
2360623606 @tagName(as),
23607 target.cpu.arch.genericName(),
23607 @tagName(target.cpu.arch.family()),
2360823608 @tagName(target.os.tag),
2360923609 },
2361023610 );
......@@ -36719,7 +36719,7 @@ pub fn analyzeAsAddressSpace(
3671936719 block,
3672036720 src,
3672136721 "{s} with address space '{s}' are not supported on {s}",
36722 .{ entity, @tagName(address_space), target.cpu.arch.genericName() },
36722 .{ entity, @tagName(address_space), @tagName(target.cpu.arch.family()) },
3672336723 );
3672436724 }
3672536725
src/Type.zig+4-4
......@@ -993,8 +993,8 @@ pub fn abiAlignmentInner(
993993 },
994994 .stage2_x86_64 => {
995995 if (vector_type.child == .bool_type) {
996 if (vector_type.len > 256 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" };
997 if (vector_type.len > 128 and std.Target.x86.featureSetHas(target.cpu.features, .avx)) return .{ .scalar = .@"32" };
996 if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .{ .scalar = .@"64" };
997 if (vector_type.len > 128 and target.cpu.has(.x86, .avx)) return .{ .scalar = .@"32" };
998998 if (vector_type.len > 64) return .{ .scalar = .@"16" };
999999 const bytes = std.math.divCeil(u32, vector_type.len, 8) catch unreachable;
10001000 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
......@@ -1003,8 +1003,8 @@ pub fn abiAlignmentInner(
10031003 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar);
10041004 if (elem_bytes == 0) return .{ .scalar = .@"1" };
10051005 const bytes = elem_bytes * vector_type.len;
1006 if (bytes > 32 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{ .scalar = .@"64" };
1007 if (bytes > 16 and std.Target.x86.featureSetHas(target.cpu.features, .avx)) return .{ .scalar = .@"32" };
1006 if (bytes > 32 and target.cpu.has(.x86, .avx512f)) return .{ .scalar = .@"64" };
1007 if (bytes > 16 and target.cpu.has(.x86, .avx)) return .{ .scalar = .@"32" };
10081008 return .{ .scalar = .@"16" };
10091009 },
10101010 }
src/Zcu.zig+2-2
......@@ -3741,7 +3741,7 @@ pub fn errorSetBits(zcu: *const Zcu) u16 {
37413741
37423742 if (zcu.error_limit == 0) return 0;
37433743 if (target.cpu.arch.isSpirV()) {
3744 if (!std.Target.spirv.featureSetHas(target.cpu.features, .storage_push_constant16)) {
3744 if (!target.cpu.has(.spirv, .storage_push_constant16)) {
37453745 return 32;
37463746 }
37473747 }
......@@ -3911,7 +3911,7 @@ pub fn atomicPtrAlignment(
39113911 .aarch64_be,
39123912 => 128,
39133913
3914 .x86_64 => if (std.Target.x86.featureSetHas(target.cpu.features, .cx16)) 128 else 64,
3914 .x86_64 => if (target.cpu.has(.x86, .cx16)) 128 else 64,
39153915 };
39163916
39173917 if (ty.toIntern() == .bool_type) return .none;
src/arch/arm/CodeGen.zig+3-3
......@@ -4344,7 +4344,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43444344
43454345 // TODO: add Instruction.supportedOn
43464346 // function for ARM
4347 if (Target.arm.featureSetHas(self.target.cpu.features, .has_v5t)) {
4347 if (self.target.cpu.has(.arm, .has_v5t)) {
43484348 _ = try self.addInst(.{
43494349 .tag = .blx,
43504350 .data = .{ .reg = .lr },
......@@ -5578,7 +5578,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
55785578 } },
55795579 });
55805580 } else if (x <= math.maxInt(u16)) {
5581 if (Target.arm.featureSetHas(self.target.cpu.features, .has_v7)) {
5581 if (self.target.cpu.has(.arm, .has_v7)) {
55825582 _ = try self.addInst(.{
55835583 .tag = .movw,
55845584 .data = .{ .r_imm16 = .{
......@@ -5606,7 +5606,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56065606 } else {
56075607 // TODO write constant to code and load
56085608 // relative to pc
5609 if (Target.arm.featureSetHas(self.target.cpu.features, .has_v7)) {
5609 if (self.target.cpu.has(.arm, .has_v7)) {
56105610 // immediate: 0xaaaabbbb
56115611 // movw reg, #0xbbbb
56125612 // movt reg, #0xaaaa
src/arch/arm/Emit.zig+2-2
......@@ -203,7 +203,7 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
203203 } else if (Instruction.Operand.fromU32(imm32) != null) {
204204 // sub
205205 return 1 * 4;
206 } else if (Target.arm.featureSetHas(emit.target.cpu.features, .has_v7)) {
206 } else if (emit.target.cpu.has(.arm, .has_v7)) {
207207 // movw; movt; sub
208208 return 3 * 4;
209209 } else {
......@@ -452,7 +452,7 @@ fn mirSubStackPointer(emit: *Emit, inst: Mir.Inst.Index) !void {
452452 const operand = Instruction.Operand.fromU32(imm32) orelse blk: {
453453 const scratch: Register = .r4;
454454
455 if (Target.arm.featureSetHas(emit.target.cpu.features, .has_v7)) {
455 if (emit.target.cpu.has(.arm, .has_v7)) {
456456 try emit.writeInstruction(Instruction.movw(cond, scratch, @as(u16, @truncate(imm32))));
457457 try emit.writeInstruction(Instruction.movt(cond, scratch, @as(u16, @truncate(imm32 >> 16))));
458458 } else {
src/arch/riscv64/CodeGen.zig+1-1
......@@ -8455,7 +8455,7 @@ fn typeOfIndex(func: *Func, inst: Air.Inst.Index) Type {
84558455}
84568456
84578457fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {
8458 return Target.riscv.featureSetHas(func.target.cpu.features, feature);
8458 return func.target.cpu.has(.riscv, feature);
84598459}
84608460
84618461pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
src/arch/riscv64/Lower.zig+1-3
......@@ -590,9 +590,7 @@ pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
590590}
591591
592592fn hasFeature(lower: *Lower, feature: std.Target.riscv.Feature) bool {
593 const target = lower.pt.zcu.getTarget();
594 const features = target.cpu.features;
595 return std.Target.riscv.featureSetHas(features, feature);
593 return lower.pt.zcu.getTarget().cpu.has(.riscv, feature);
596594}
597595
598596const Lower = @This();
src/arch/riscv64/abi.zig+3-4
......@@ -22,7 +22,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {
2222 return .byval;
2323 }
2424
25 if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: {
25 if (target.cpu.has(.riscv, .d)) fields: {
2626 var any_fp = false;
2727 var field_count: usize = 0;
2828 for (0..ty.structFieldCount(zcu)) |field_index| {
......@@ -141,10 +141,9 @@ pub fn classifySystem(ty: Type, zcu: *Zcu) [8]SystemClass {
141141 },
142142 .float => {
143143 const target = zcu.getTarget();
144 const features = target.cpu.features;
145144
146 const float_bits = ty.floatBits(zcu.getTarget());
147 const float_reg_size: u32 = if (std.Target.riscv.featureSetHas(features, .d)) 64 else 32;
145 const float_bits = ty.floatBits(target);
146 const float_reg_size: u32 = if (target.cpu.has(.riscv, .d)) 64 else 32;
148147 if (float_bits <= float_reg_size) {
149148 result[0] = .float;
150149 return result;
src/arch/riscv64/bits.zig+6-8
......@@ -164,12 +164,12 @@ pub const Register = enum(u8) {
164164 ft8, ft9, ft10, ft11, // foat temporaries. calller saved.
165165
166166 // this register is accessed only through API instructions instead of directly
167 // fcsr,
167 // fcsr,
168168
169 f0, f1, f2, f3, f4, f5, f6, f7,
170 f8, f9, f10, f11, f12, f13, f14, f15,
171 f16, f17, f18, f19, f20, f21, f22, f23,
172 f24, f25, f26, f27, f28, f29, f30, f31,
169 f0, f1, f2, f3, f4, f5, f6, f7,
170 f8, f9, f10, f11, f12, f13, f14, f15,
171 f16, f17, f18, f19, f20, f21, f22, f23,
172 f24, f25, f26, f27, f28, f29, f30, f31,
173173
174174
175175 // V extension registers
......@@ -211,12 +211,10 @@ pub const Register = enum(u8) {
211211 }
212212
213213 pub fn bitSize(reg: Register, zcu: *const Zcu) u32 {
214 const features = zcu.getTarget().cpu.features;
215
216214 return switch (@intFromEnum(reg)) {
217215 // zig fmt: off
218216 @intFromEnum(Register.zero) ... @intFromEnum(Register.x31) => 64,
219 @intFromEnum(Register.ft0) ... @intFromEnum(Register.f31) => if (Target.riscv.featureSetHas(features, .d)) 64 else 32,
217 @intFromEnum(Register.ft0) ... @intFromEnum(Register.f31) => if (zcu.getTarget().cpu.has(.riscv, .d)) 64 else 32,
220218 @intFromEnum(Register.v0) ... @intFromEnum(Register.v31) => 256, // TODO: look at suggestVectorSize
221219 else => unreachable,
222220 // zig fmt: on
src/arch/wasm/CodeGen.zig+6-8
......@@ -1616,8 +1616,8 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16161616 };
16171617 // When bulk_memory is enabled, we lower it to wasm's memcpy instruction.
16181618 // If not, we lower it ourselves manually
1619 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {
1620 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
1619 if (cg.target.cpu.has(.wasm, .bulk_memory)) {
1620 const len0_ok = cg.target.cpu.has(.wasm, .nontrapping_bulk_memory_len0);
16211621 const emit_check = !(len0_ok or len_known_neq_0);
16221622
16231623 if (emit_check) {
......@@ -1839,9 +1839,7 @@ const SimdStoreStrategy = enum {
18391839pub fn determineSimdStoreStrategy(ty: Type, zcu: *const Zcu, target: *const std.Target) SimdStoreStrategy {
18401840 assert(ty.zigTypeTag(zcu) == .vector);
18411841 if (ty.bitSize(zcu) != 128) return .unrolled;
1842 const hasFeature = std.Target.wasm.featureSetHas;
1843 const features = target.cpu.features;
1844 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {
1842 if (target.cpu.has(.wasm, .relaxed_simd) or target.cpu.has(.wasm, .simd128)) {
18451843 return .direct;
18461844 }
18471845 return .unrolled;
......@@ -4838,8 +4836,8 @@ fn memset(cg: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue)
48384836
48394837 // When bulk_memory is enabled, we lower it to wasm's memset instruction.
48404838 // If not, we lower it ourselves.
4841 if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory) and abi_size == 1) {
4842 const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
4839 if (cg.target.cpu.has(.wasm, .bulk_memory) and abi_size == 1) {
4840 const len0_ok = cg.target.cpu.has(.wasm, .nontrapping_bulk_memory_len0);
48434841
48444842 if (!len0_ok) {
48454843 try cg.startBlock(.block, .empty);
......@@ -7304,7 +7302,7 @@ fn airErrorSetHasValue(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
73047302}
73057303
73067304inline fn useAtomicFeature(cg: *const CodeGen) bool {
7307 return std.Target.wasm.featureSetHas(cg.target.cpu.features, .atomics);
7305 return cg.target.cpu.has(.wasm, .atomics);
73087306}
73097307
73107308fn airCmpxchg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
src/arch/x86_64/CodeGen.zig+1-1
......@@ -182035,7 +182035,7 @@ fn hasFeature(cg: *CodeGen, feature: std.Target.x86.Feature) bool {
182035182035 .x86_64 => null,
182036182036 },
182037182037 else => null,
182038 } orelse std.Target.x86.featureSetHas(cg.target.cpu.features, feature);
182038 } orelse cg.target.cpu.has(.x86, feature);
182039182039}
182040182040
182041182041fn typeOf(self: *CodeGen, inst: Air.Inst.Ref) Type {
src/arch/x86_64/Encoding.zig+6-6
......@@ -72,8 +72,8 @@ pub fn findByMnemonic(
7272 },
7373 inline .@"invpcid 32bit", .@"rdpid 32bit" => |tag| switch (target.cpu.arch) {
7474 else => unreachable,
75 .x86 => std.Target.x86.featureSetHas(
76 target.cpu.features,
75 .x86 => target.cpu.has(
76 .x86,
7777 @field(std.Target.x86.Feature, @tagName(tag)[0 .. @tagName(tag).len - " 32bit".len]),
7878 ),
7979 .x86_64 => false,
......@@ -81,17 +81,17 @@ pub fn findByMnemonic(
8181 inline .@"invpcid 64bit", .@"rdpid 64bit", .@"prefetchi 64bit" => |tag| switch (target.cpu.arch) {
8282 else => unreachable,
8383 .x86 => false,
84 .x86_64 => std.Target.x86.featureSetHas(
85 target.cpu.features,
84 .x86_64 => target.cpu.has(
85 .x86,
8686 @field(std.Target.x86.Feature, @tagName(tag)[0 .. @tagName(tag).len - " 64bit".len]),
8787 ),
8888 },
89 .prefetch => std.Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .prfchw, .prefetchi, .prefetchwt1 }),
89 .prefetch => target.cpu.hasAny(.x86, &.{ .sse, .prfchw, .prefetchi, .prefetchwt1 }),
9090 inline else => |tag| has_features: {
9191 comptime var feature_it = std.mem.splitScalar(u8, @tagName(tag), ' ');
9292 comptime var features: []const std.Target.x86.Feature = &.{};
9393 inline while (comptime feature_it.next()) |feature| features = features ++ .{@field(std.Target.x86.Feature, feature)};
94 break :has_features std.Target.x86.featureSetHasAll(target.cpu.features, features[0..].*);
94 break :has_features target.cpu.hasAll(.x86, features);
9595 },
9696 }) continue;
9797
src/arch/x86_64/abi.zig+6-6
......@@ -201,11 +201,11 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
201201 .integer_per_element, .none, .none, .none,
202202 .none, .none, .none, .none,
203203 };
204 if (bits <= 256 and std.Target.x86.featureSetHas(target.cpu.features, .avx)) return .{
204 if (bits <= 256 and target.cpu.has(.x86, .avx)) return .{
205205 .integer_per_element, .none, .none, .none,
206206 .none, .none, .none, .none,
207207 };
208 if (bits <= 512 and std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return .{
208 if (bits <= 512 and target.cpu.has(.x86, .avx512f)) return .{
209209 .integer_per_element, .none, .none, .none,
210210 .none, .none, .none, .none,
211211 };
......@@ -220,7 +220,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
220220 .sse, .sseup, .none, .none,
221221 .none, .none, .none, .none,
222222 };
223 if (ctx == .arg and !std.Target.x86.featureSetHas(target.cpu.features, .avx)) return memory_class;
223 if (ctx == .arg and !target.cpu.has(.x86, .avx)) return memory_class;
224224 if (bits <= 192) return .{
225225 .sse, .sseup, .sseup, .none,
226226 .none, .none, .none, .none,
......@@ -229,7 +229,7 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
229229 .sse, .sseup, .sseup, .sseup,
230230 .none, .none, .none, .none,
231231 };
232 if (ctx == .arg and !std.Target.x86.featureSetHas(target.cpu.features, .avx512f)) return memory_class;
232 if (ctx == .arg and !target.cpu.has(.x86, .avx512f)) return memory_class;
233233 if (bits <= 320) return .{
234234 .sse, .sseup, .sseup, .sseup,
235235 .sseup, .none, .none, .none,
......@@ -242,9 +242,9 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
242242 .sse, .sseup, .sseup, .sseup,
243243 .sseup, .sseup, .sseup, .none,
244244 };
245 if (bits <= 512 or (ctx == .ret and bits <= @as(u64, if (std.Target.x86.featureSetHas(target.cpu.features, .avx512f))
245 if (bits <= 512 or (ctx == .ret and bits <= @as(u64, if (target.cpu.has(.x86, .avx512f))
246246 2048
247 else if (std.Target.x86.featureSetHas(target.cpu.features, .avx))
247 else if (target.cpu.has(.x86, .avx))
248248 1024
249249 else
250250 512))) return .{
src/codegen/llvm.zig+24-26
......@@ -40,9 +40,9 @@ pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
4040 return null;
4141}
4242
43fn subArchName(features: std.Target.Cpu.Feature.Set, arch: anytype, mappings: anytype) ?[]const u8 {
43fn subArchName(target: std.Target, comptime family: std.Target.Cpu.Arch.Family, mappings: anytype) ?[]const u8 {
4444 inline for (mappings) |mapping| {
45 if (arch.featureSetHas(features, mapping[0])) return mapping[1];
45 if (target.cpu.has(family, mapping[0])) return mapping[1];
4646 }
4747
4848 return null;
......@@ -52,8 +52,6 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
5252 var llvm_triple = std.ArrayList(u8).init(allocator);
5353 defer llvm_triple.deinit();
5454
55 const features = target.cpu.features;
56
5755 const llvm_arch = switch (target.cpu.arch) {
5856 .arm => "arm",
5957 .armeb => "armeb",
......@@ -69,10 +67,10 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
6967 .loongarch64 => "loongarch64",
7068 .m68k => "m68k",
7169 // MIPS sub-architectures are a bit irregular, so we handle them manually here.
72 .mips => if (std.Target.mips.featureSetHas(features, .mips32r6)) "mipsisa32r6" else "mips",
73 .mipsel => if (std.Target.mips.featureSetHas(features, .mips32r6)) "mipsisa32r6el" else "mipsel",
74 .mips64 => if (std.Target.mips.featureSetHas(features, .mips64r6)) "mipsisa64r6" else "mips64",
75 .mips64el => if (std.Target.mips.featureSetHas(features, .mips64r6)) "mipsisa64r6el" else "mips64el",
70 .mips => if (target.cpu.has(.mips, .mips32r6)) "mipsisa32r6" else "mips",
71 .mipsel => if (target.cpu.has(.mips, .mips32r6)) "mipsisa32r6el" else "mipsel",
72 .mips64 => if (target.cpu.has(.mips, .mips64r6)) "mipsisa64r6" else "mips64",
73 .mips64el => if (target.cpu.has(.mips, .mips64r6)) "mipsisa64r6el" else "mips64el",
7674 .msp430 => "msp430",
7775 .powerpc => "powerpc",
7876 .powerpcle => "powerpcle",
......@@ -109,7 +107,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
109107 try llvm_triple.appendSlice(llvm_arch);
110108
111109 const llvm_sub_arch: ?[]const u8 = switch (target.cpu.arch) {
112 .arm, .armeb, .thumb, .thumbeb => subArchName(features, std.Target.arm, .{
110 .arm, .armeb, .thumb, .thumbeb => subArchName(target, .arm, .{
113111 .{ .v4t, "v4t" },
114112 .{ .v5t, "v5t" },
115113 .{ .v5te, "v5te" },
......@@ -146,13 +144,13 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
146144 .{ .v9_5a, "v9.5a" },
147145 .{ .v9_6a, "v9.6a" },
148146 }),
149 .powerpc => subArchName(features, std.Target.powerpc, .{
147 .powerpc => subArchName(target, .powerpc, .{
150148 .{ .spe, "spe" },
151149 }),
152 .spirv => subArchName(features, std.Target.spirv, .{
150 .spirv => subArchName(target, .spirv, .{
153151 .{ .v1_5, "1.5" },
154152 }),
155 .spirv32, .spirv64 => subArchName(features, std.Target.spirv, .{
153 .spirv32, .spirv64 => subArchName(target, .spirv, .{
156154 .{ .v1_5, "1.5" },
157155 .{ .v1_4, "1.4" },
158156 .{ .v1_3, "1.3" },
......@@ -309,13 +307,13 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
309307}
310308
311309pub fn supportsTailCall(target: std.Target) bool {
312 switch (target.cpu.arch) {
313 .wasm32, .wasm64 => return std.Target.wasm.featureSetHas(target.cpu.features, .tail_call),
310 return switch (target.cpu.arch) {
311 .wasm32, .wasm64 => target.cpu.has(.wasm, .tail_call),
314312 // Although these ISAs support tail calls, LLVM does not support tail calls on them.
315 .mips, .mipsel, .mips64, .mips64el => return false,
316 .powerpc, .powerpcle, .powerpc64, .powerpc64le => return false,
317 else => return true,
318 }
313 .mips, .mipsel, .mips64, .mips64el => false,
314 .powerpc, .powerpcle, .powerpc64, .powerpc64le => false,
315 else => true,
316 };
319317}
320318
321319pub fn dataLayout(target: std.Target) []const u8 {
......@@ -391,11 +389,11 @@ pub fn dataLayout(target: std.Target) []const u8 {
391389 .nvptx => "e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64",
392390 .nvptx64 => "e-i64:64-i128:128-v16:16-v32:32-n16:32:64",
393391 .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",
394 .riscv32 => if (std.Target.riscv.featureSetHas(target.cpu.features, .e))
392 .riscv32 => if (target.cpu.has(.riscv, .e))
395393 "e-m:e-p:32:32-i64:64-n32-S32"
396394 else
397395 "e-m:e-p:32:32-i64:64-n32-S128",
398 .riscv64 => if (std.Target.riscv.featureSetHas(target.cpu.features, .e))
396 .riscv64 => if (target.cpu.has(.riscv, .e))
399397 "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"
400398 else
401399 "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
......@@ -12047,7 +12045,7 @@ fn returnTypeByRef(zcu: *Zcu, target: std.Target, ty: Type) bool {
1204712045 if (isByRef(ty, zcu)) {
1204812046 return true;
1204912047 } else if (target.cpu.arch.isX86() and
12050 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
12048 !target.cpu.has(.x86, .evex512) and
1205112049 ty.totalVectorBits(zcu) >= 512)
1205212050 {
1205312051 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
......@@ -12322,7 +12320,7 @@ const ParamTypeIterator = struct {
1232212320 } else if (isByRef(ty, zcu)) {
1232312321 return .byref;
1232412322 } else if (target.cpu.arch.isX86() and
12325 !std.Target.x86.featureSetHas(target.cpu.features, .evex512) and
12323 !target.cpu.has(.x86, .evex512) and
1232612324 ty.totalVectorBits(zcu) >= 512)
1232712325 {
1232812326 // As of LLVM 18, passing a vector byval with fastcc that is 512 bits or more returns
......@@ -12746,7 +12744,7 @@ fn isScalar(zcu: *Zcu, ty: Type) bool {
1274612744/// or if it produces miscompilations.
1274712745fn backendSupportsF80(target: std.Target) bool {
1274812746 return switch (target.cpu.arch) {
12749 .x86_64, .x86 => !std.Target.x86.featureSetHas(target.cpu.features, .soft_float),
12747 .x86, .x86_64 => !target.cpu.has(.x86, .soft_float),
1275012748 else => false,
1275112749 };
1275212750}
......@@ -12778,11 +12776,11 @@ fn backendSupportsF16(target: std.Target) bool {
1277812776 .armeb,
1277912777 .thumb,
1278012778 .thumbeb,
12781 => target.abi.float() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fullfp16),
12779 => target.abi.float() == .soft or target.cpu.has(.arm, .fullfp16),
1278212780 // https://github.com/llvm/llvm-project/issues/129394
1278312781 .aarch64,
1278412782 .aarch64_be,
12785 => std.Target.aarch64.featureSetHas(target.cpu.features, .fp_armv8),
12783 => target.cpu.has(.aarch64, .fp_armv8),
1278612784 else => true,
1278712785 };
1278812786}
......@@ -12813,7 +12811,7 @@ fn backendSupportsF128(target: std.Target) bool {
1281312811 .armeb,
1281412812 .thumb,
1281512813 .thumbeb,
12816 => target.abi.float() == .soft or std.Target.arm.featureSetHas(target.cpu.features, .fp_armv8),
12814 => target.abi.float() == .soft or target.cpu.has(.arm, .fp_armv8),
1281712815 else => true,
1281812816 };
1281912817}
src/codegen/spirv/Module.zig+7-7
......@@ -190,12 +190,12 @@ entry_points: std.AutoArrayHashMapUnmanaged(IdRef, EntryPoint) = .empty,
190190pub fn init(gpa: Allocator, target: std.Target) Module {
191191 const version_minor: u8 = blk: {
192192 // Prefer higher versions
193 if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_6)) break :blk 6;
194 if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_5)) break :blk 5;
195 if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_4)) break :blk 4;
196 if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_3)) break :blk 3;
197 if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_2)) break :blk 2;
198 if (std.Target.spirv.featureSetHas(target.cpu.features, .v1_1)) break :blk 1;
193 if (target.cpu.has(.spirv, .v1_6)) break :blk 6;
194 if (target.cpu.has(.spirv, .v1_5)) break :blk 5;
195 if (target.cpu.has(.spirv, .v1_4)) break :blk 4;
196 if (target.cpu.has(.spirv, .v1_3)) break :blk 3;
197 if (target.cpu.has(.spirv, .v1_2)) break :blk 2;
198 if (target.cpu.has(.spirv, .v1_1)) break :blk 1;
199199 break :blk 0;
200200 };
201201
......@@ -268,7 +268,7 @@ pub fn idBound(self: Module) Word {
268268}
269269
270270pub fn hasFeature(self: *Module, feature: std.Target.spirv.Feature) bool {
271 return std.Target.spirv.featureSetHas(self.target.cpu.features, feature);
271 return self.target.cpu.has(.spirv, feature);
272272}
273273
274274fn addEntryPointDeps(
src/link/Elf/Object.zig+5-6
......@@ -187,7 +187,6 @@ pub fn validateEFlags(
187187) !void {
188188 switch (target.cpu.arch) {
189189 .riscv64 => {
190 const features = target.cpu.features;
191190 const flags: riscv.Eflags = @bitCast(e_flags);
192191 var any_errors: bool = false;
193192
......@@ -196,7 +195,7 @@ pub fn validateEFlags(
196195
197196 // Invalid when
198197 // 1. The input uses C and we do not.
199 if (flags.rvc and !std.Target.riscv.featureSetHas(features, .c)) {
198 if (flags.rvc and !target.cpu.has(.riscv, .c)) {
200199 any_errors = true;
201200 diags.addParseError(
202201 path,
......@@ -208,7 +207,7 @@ pub fn validateEFlags(
208207 // Invalid when
209208 // 1. We use E and the input does not.
210209 // 2. The input uses E and we do not.
211 if (std.Target.riscv.featureSetHas(features, .e) != flags.rve) {
210 if (target.cpu.has(.riscv, .e) != flags.rve) {
212211 any_errors = true;
213212 diags.addParseError(
214213 path,
......@@ -225,7 +224,7 @@ pub fn validateEFlags(
225224 // Invalid when
226225 // 1. We use total store order and the input does not.
227226 // 2. The input uses total store order and we do not.
228 if (flags.tso != std.Target.riscv.featureSetHas(features, .ztso)) {
227 if (flags.tso != target.cpu.has(.riscv, .ztso)) {
229228 any_errors = true;
230229 diags.addParseError(
231230 path,
......@@ -235,9 +234,9 @@ pub fn validateEFlags(
235234 }
236235
237236 const fabi: riscv.Eflags.FloatAbi =
238 if (std.Target.riscv.featureSetHas(features, .d))
237 if (target.cpu.has(.riscv, .d))
239238 .double
240 else if (std.Target.riscv.featureSetHas(features, .f))
239 else if (target.cpu.has(.riscv, .f))
241240 .single
242241 else
243242 .soft;
src/link/Wasm/Flush.zig+1-1
......@@ -1159,7 +1159,7 @@ fn emitFeaturesSection(
11591159
11601160 var safety_count = feature_count;
11611161 for (target.cpu.arch.allFeaturesList(), 0..) |*feature, i| {
1162 if (!std.Target.wasm.featureSetHas(target.cpu.features, @enumFromInt(i))) continue;
1162 if (!target.cpu.has(.wasm, @as(std.Target.wasm.Feature, @enumFromInt(i)))) continue;
11631163 safety_count -= 1;
11641164
11651165 try leb.writeUleb128(writer, @as(u32, '+'));
src/link/Wasm/Object.zig+5-5
......@@ -917,12 +917,12 @@ pub fn parse(
917917 }
918918 if (!saw_linking_section) return error.MissingLinkingSection;
919919
920 const target_features = comp.root_mod.resolved_target.result.cpu.features;
920 const cpu = comp.root_mod.resolved_target.result.cpu;
921921
922922 if (has_tls) {
923 if (!std.Target.wasm.featureSetHas(target_features, .atomics))
923 if (!cpu.has(.wasm, .atomics))
924924 return diags.failParse(path, "object has TLS segment but target CPU feature atomics is disabled", .{});
925 if (!std.Target.wasm.featureSetHas(target_features, .bulk_memory))
925 if (!cpu.has(.wasm, .bulk_memory))
926926 return diags.failParse(path, "object has TLS segment but target CPU feature bulk_memory is disabled", .{});
927927 }
928928
......@@ -937,7 +937,7 @@ pub fn parse(
937937 },
938938 else => {
939939 const f = feat.tag.toCpuFeature().?;
940 if (std.Target.wasm.featureSetHas(target_features, f)) {
940 if (cpu.has(.wasm, f)) {
941941 return diags.failParse(
942942 path,
943943 "object forbids {s} but specified target features include {s}",
......@@ -952,7 +952,7 @@ pub fn parse(
952952 },
953953 else => {
954954 const f = feat.tag.toCpuFeature().?;
955 if (!std.Target.wasm.featureSetHas(target_features, f)) {
955 if (!cpu.has(.wasm, f)) {
956956 return diags.failParse(
957957 path,
958958 "object requires {s} but specified target features exclude {s}",
src/target.zig+32-35
......@@ -297,18 +297,21 @@ pub fn classifyCompilerRtLibName(name: []const u8) CompilerRtClassification {
297297
298298pub fn hasDebugInfo(target: std.Target) bool {
299299 return switch (target.cpu.arch) {
300 .nvptx, .nvptx64 => std.Target.nvptx.featureSetHas(target.cpu.features, .ptx75) or
301 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx76) or
302 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx77) or
303 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx78) or
304 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx80) or
305 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx81) or
306 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx82) or
307 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx83) or
308 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx84) or
309 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx85) or
310 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx86) or
311 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx87),
300 // TODO: We should make newer PTX versions depend on older ones so we'd just check `ptx75`.
301 .nvptx, .nvptx64 => target.cpu.hasAny(.nvptx, &.{
302 .ptx75,
303 .ptx76,
304 .ptx77,
305 .ptx78,
306 .ptx80,
307 .ptx81,
308 .ptx82,
309 .ptx83,
310 .ptx84,
311 .ptx85,
312 .ptx86,
313 .ptx87,
314 }),
312315 .bpfel, .bpfeb => false,
313316 else => true,
314317 };
......@@ -613,28 +616,22 @@ pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
613616 else => if (target.abi.isMusl()) "elfv2" else "elfv1",
614617 },
615618 .powerpc64le => "elfv2",
616 .riscv64 => b: {
617 const featureSetHas = std.Target.riscv.featureSetHas;
618 break :b if (featureSetHas(target.cpu.features, .e))
619 "lp64e"
620 else if (featureSetHas(target.cpu.features, .d))
621 "lp64d"
622 else if (featureSetHas(target.cpu.features, .f))
623 "lp64f"
624 else
625 "lp64";
626 },
627 .riscv32 => b: {
628 const featureSetHas = std.Target.riscv.featureSetHas;
629 break :b if (featureSetHas(target.cpu.features, .e))
630 "ilp32e"
631 else if (featureSetHas(target.cpu.features, .d))
632 "ilp32d"
633 else if (featureSetHas(target.cpu.features, .f))
634 "ilp32f"
635 else
636 "ilp32";
637 },
619 .riscv64 => if (target.cpu.has(.riscv, .e))
620 "lp64e"
621 else if (target.cpu.has(.riscv, .d))
622 "lp64d"
623 else if (target.cpu.has(.riscv, .f))
624 "lp64f"
625 else
626 "lp64",
627 .riscv32 => if (target.cpu.has(.riscv, .e))
628 "ilp32e"
629 else if (target.cpu.has(.riscv, .d))
630 "ilp32d"
631 else if (target.cpu.has(.riscv, .f))
632 "ilp32f"
633 else
634 "ilp32",
638635 else => null,
639636 };
640637}
......@@ -672,7 +669,7 @@ pub fn minFunctionAlignment(target: std.Target) Alignment {
672669 return switch (target.cpu.arch) {
673670 .riscv32,
674671 .riscv64,
675 => if (std.Target.riscv.featureSetHasAny(target.cpu.features, .{ .c, .zca })) .@"2" else .@"4",
672 => if (target.cpu.hasAny(.riscv, &.{ .c, .zca })) .@"2" else .@"4",
676673 .thumb,
677674 .thumbeb,
678675 .csky,
test/behavior/atomics.zig+1-1
......@@ -7,7 +7,7 @@ const supports_128_bit_atomics = switch (builtin.cpu.arch) {
77 // TODO: Ideally this could be sync'd with the logic in Sema.
88 .aarch64 => true,
99 .aarch64_be => false, // Fails due to LLVM issues.
10 .x86_64 => std.Target.x86.featureSetHas(builtin.cpu.features, .cx16),
10 .x86_64 => builtin.cpu.has(.x86, .cx16),
1111 else => false,
1212};
1313
test/behavior/floatop.zig+12-12
......@@ -17,7 +17,7 @@ test "add f16" {
1717 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1818
1919 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
20 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
20 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
2121
2222 try testAdd(f16);
2323 try comptime testAdd(f16);
......@@ -129,7 +129,7 @@ test "cmp f16" {
129129 if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
130130
131131 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
132 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
132 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
133133
134134 try testCmp(f16);
135135 try comptime testCmp(f16);
......@@ -345,7 +345,7 @@ test "different sized float comparisons" {
345345 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
346346
347347 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
348 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
348 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
349349
350350 try testDifferentSizedFloatComparisons();
351351 try comptime testDifferentSizedFloatComparisons();
......@@ -396,7 +396,7 @@ test "@sqrt f16" {
396396 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
397397
398398 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
399 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
399 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
400400
401401 try testSqrt(f16);
402402 try comptime testSqrt(f16);
......@@ -1140,7 +1140,7 @@ test "@abs f16" {
11401140 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11411141
11421142 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1143 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
1143 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
11441144
11451145 try testFabs(f16);
11461146 try comptime testFabs(f16);
......@@ -1276,7 +1276,7 @@ test "@floor f32/f64" {
12761276 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12771277
12781278 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1279 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1279 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
12801280
12811281 try testFloor(f32);
12821282 try comptime testFloor(f32);
......@@ -1343,7 +1343,7 @@ test "@floor with vectors" {
13431343 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13441344
13451345 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1346 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1346 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
13471347
13481348 try testFloorWithVectors();
13491349 try comptime testFloorWithVectors();
......@@ -1377,7 +1377,7 @@ test "@ceil f32/f64" {
13771377 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13781378
13791379 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1380 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1380 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
13811381
13821382 try testCeil(f32);
13831383 try comptime testCeil(f32);
......@@ -1444,7 +1444,7 @@ test "@ceil with vectors" {
14441444 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14451445
14461446 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1447 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1447 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
14481448
14491449 try testCeilWithVectors();
14501450 try comptime testCeilWithVectors();
......@@ -1478,7 +1478,7 @@ test "@trunc f32/f64" {
14781478 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
14791479
14801480 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1481 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1481 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
14821482
14831483 try testTrunc(f32);
14841484 try comptime testTrunc(f32);
......@@ -1545,7 +1545,7 @@ test "@trunc with vectors" {
15451545 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15461546
15471547 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1548 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1548 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
15491549
15501550 try testTruncWithVectors();
15511551 try comptime testTruncWithVectors();
......@@ -1568,7 +1568,7 @@ test "neg f16" {
15681568 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15691569
15701570 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1571 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
1571 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
15721572
15731573 if (builtin.os.tag == .freebsd) {
15741574 // TODO file issue to track this failure
test/behavior/math.zig+2-2
......@@ -475,7 +475,7 @@ test "division" {
475475 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
476476
477477 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
478 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
478 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
479479
480480 try testIntDivision();
481481 try comptime testIntDivision();
......@@ -1930,7 +1930,7 @@ test "float vector division of comptime zero by runtime nan is nan" {
19301930 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
19311931
19321932 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
1933 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest;
1933 !comptime builtin.cpu.has(.x86, .sse4_1)) return error.SkipZigTest;
19341934
19351935 const ct_zero: @Vector(1, f32) = .{0};
19361936 var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
test/behavior/muladd.zig+3-3
......@@ -10,7 +10,7 @@ test "@mulAdd" {
1010 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1111
1212 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
13 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
13 !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest;
1414
1515 try comptime testMulAdd();
1616 try testMulAdd();
......@@ -143,7 +143,7 @@ test "vector f32" {
143143 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
144144
145145 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
146 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
146 !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest;
147147
148148 try comptime vector32();
149149 try vector32();
......@@ -171,7 +171,7 @@ test "vector f64" {
171171 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
172172
173173 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
174 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
174 !comptime builtin.cpu.has(.x86, .fma)) return error.SkipZigTest;
175175
176176 try comptime vector64();
177177 try vector64();
test/behavior/vector.zig+2-4
......@@ -251,7 +251,7 @@ test "array to vector with element type coercion" {
251251 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
252252
253253 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt == .coff and
254 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .f16c)) return error.SkipZigTest;
254 !comptime builtin.cpu.has(.x86, .f16c)) return error.SkipZigTest;
255255
256256 const S = struct {
257257 fn doTheTest() !void {
......@@ -1259,9 +1259,7 @@ test "byte vector initialized in inline function" {
12591259 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
12601260 if (builtin.cpu.arch == .aarch64_be and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
12611261
1262 if (comptime builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and
1263 std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f))
1264 {
1262 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and comptime builtin.cpu.has(.x86, .avx512f)) {
12651263 // TODO https://github.com/ziglang/zig/issues/13279
12661264 return error.SkipZigTest;
12671265 }
test/behavior/x86_64/build.zig+1-1
......@@ -133,7 +133,7 @@ pub fn build(b: *std.Build) void {
133133 .use_lld = false,
134134 .root_module = test_mod,
135135 });
136 if (!std.Target.x86.featureSetHas(target.result.cpu.features, .sse2)) {
136 if (!target.result.cpu.has(.x86, .sse2)) {
137137 test_exe.bundle_compiler_rt = false;
138138 test_mod.linkLibrary(compiler_rt_lib);
139139 }
test/behavior/x86_64/math.zig+1-1
......@@ -17,7 +17,7 @@ pub const Gpr = switch (builtin.cpu.arch) {
1717 .x86 => u32,
1818 .x86_64 => u64,
1919};
20pub const Sse = if (std.Target.x86.featureSetHas(builtin.cpu.features, .avx))
20pub const Sse = if (builtin.cpu.has(.x86, .avx))
2121 @Vector(32, u8)
2222else
2323 @Vector(16, u8);
test/c_abi/main.zig+1-3
......@@ -1087,9 +1087,7 @@ extern fn c_medium_vec(MediumVec) void;
10871087extern fn c_ret_medium_vec() MediumVec;
10881088
10891089test "medium simd vector" {
1090 if (builtin.zig_backend == .stage2_x86_64 and
1091 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx)) return error.SkipZigTest;
1092
1090 if (builtin.zig_backend == .stage2_x86_64 and !comptime builtin.cpu.has(.x86, .avx)) return error.SkipZigTest;
10931091 if (builtin.cpu.arch.isPowerPC64()) return error.SkipZigTest;
10941092
10951093 c_medium_vec(.{ 1, 2, 3, 4 });
tools/gen_outline_atomics.zig+1-1
......@@ -25,7 +25,7 @@ pub fn main() !void {
2525 \\const builtin = @import("builtin");
2626 \\const std = @import("std");
2727 \\const common = @import("common.zig");
28 \\const always_has_lse = std.Target.aarch64.featureSetHas(builtin.cpu.features, .lse);
28 \\const always_has_lse = builtin.cpu.has(.aarch64, .lse);
2929 \\
3030 \\/// This default is overridden at runtime after inspecting CPU properties.
3131 \\/// It is intentionally not exported in order to make the machine code that