From ce8c61b0fcb7e0610d4b39728b2d73ed10e762f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 24 Jan 2025 02:04:51 +0100 Subject: [PATCH] std.Target: Move Cpu.Arch.supportsAddressSpace() up to Cpu. This allows it to inspect CPU features which is needed for Propeller, and AVR in the future. --- lib/std/Target.zig | 57 +++++++++++++++++++++++----------------------- src/Sema.zig | 5 ++-- src/target.zig | 9 ++++---- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 7eb17b1297..8b271fd563 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1576,34 +1576,6 @@ pub const Cpu = struct { }; } - /// Returns whether this architecture supports `address_space`. If `context` is `null`, this - /// function simply answers the general question of whether the architecture has any concept - /// of `address_space`; if non-`null`, the function additionally checks whether - /// `address_space` is valid in that context. - pub fn supportsAddressSpace( - arch: Arch, - address_space: std.builtin.AddressSpace, - context: ?std.builtin.AddressSpace.Context, - ) bool { - const is_nvptx = arch.isNvptx(); - const is_spirv = arch.isSpirV(); - const is_gpu = is_nvptx or is_spirv or arch == .amdgcn; - return switch (address_space) { - .generic => true, - .fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer), - .global, .local, .shared => is_gpu, - .constant => is_gpu and (context == null or context == .constant), - .param => is_nvptx, - .input, .output, .uniform, .push_constant, .storage_buffer => is_spirv, - // TODO this should also check how many flash banks the cpu has - .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, - - // Propeller address spaces: - .cog, .hub => arch == .propeller, - .lut => arch == .propeller, // TODO: This should check for the `p2` CPU feature. - }; - } - /// Returns a name that matches the lib/std/target/* source file name. pub fn genericName(arch: Arch) [:0]const u8 { return switch (arch) { @@ -1999,6 +1971,35 @@ pub const Cpu = struct { pub fn baseline(arch: Arch, os: Os) Cpu { return Model.baseline(arch, os).toCpu(arch); } + + /// Returns whether this architecture supports `address_space`. If `context` is `null`, this + /// function simply answers the general question of whether the architecture has any concept + /// of `address_space`; if non-`null`, the function additionally checks whether + /// `address_space` is valid in that context. + pub fn supportsAddressSpace( + cpu: Cpu, + address_space: std.builtin.AddressSpace, + context: ?std.builtin.AddressSpace.Context, + ) bool { + const arch = cpu.arch; + + const is_nvptx = arch.isNvptx(); + const is_spirv = arch.isSpirV(); + const is_gpu = is_nvptx or is_spirv or arch == .amdgcn; + + return switch (address_space) { + .generic => true, + .fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer), + .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, // TODO this should also check how many flash banks the cpu has + .cog, .hub => arch == .propeller, + .lut => arch == .propeller and std.Target.propeller.featureSetHas(cpu.features, .p2), + + .global, .local, .shared => is_gpu, + .constant => is_gpu and (context == null or context == .constant), + .param => is_nvptx, + .input, .output, .uniform, .push_constant, .storage_buffer => is_spirv, + }; + } }; pub fn zigTriple(target: Target, allocator: Allocator) Allocator.Error![]u8 { diff --git a/src/Sema.zig b/src/Sema.zig index 1fbec0ecc4..78a7a8f658 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -37244,9 +37244,8 @@ pub fn analyzeAsAddressSpace( const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" }); const address_space = try sema.interpretBuiltinType(block, src, addrspace_val, std.builtin.AddressSpace); const target = pt.zcu.getTarget(); - const arch = target.cpu.arch; - if (!arch.supportsAddressSpace(address_space, ctx)) { + if (!target.cpu.supportsAddressSpace(address_space, ctx)) { // TODO error messages could be made more elaborate here const entity = switch (ctx) { .function => "functions", @@ -37258,7 +37257,7 @@ pub fn analyzeAsAddressSpace( block, src, "{s} with address space '{s}' are not supported on {s}", - .{ entity, @tagName(address_space), arch.genericName() }, + .{ entity, @tagName(address_space), target.cpu.arch.genericName() }, ); } diff --git a/src/target.zig b/src/target.zig index ed28657e20..621cac3479 100644 --- a/src/target.zig +++ b/src/target.zig @@ -442,12 +442,11 @@ pub fn addrSpaceCastIsValid( from: AddressSpace, to: AddressSpace, ) bool { - const arch = target.cpu.arch; - switch (arch) { - .x86_64, .x86 => return arch.supportsAddressSpace(from, null) and arch.supportsAddressSpace(to, null), + switch (target.cpu.arch) { + .x86_64, .x86 => return target.cpu.supportsAddressSpace(from, null) and target.cpu.supportsAddressSpace(to, null), .nvptx64, .nvptx, .amdgcn => { - const to_generic = arch.supportsAddressSpace(from, null) and to == .generic; - const from_generic = arch.supportsAddressSpace(to, null) and from == .generic; + const to_generic = target.cpu.supportsAddressSpace(from, null) and to == .generic; + const from_generic = target.cpu.supportsAddressSpace(to, null) and from == .generic; return to_generic or from_generic; }, else => return from == .generic and to == .generic,