authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-01-24 02:04:51+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-17 19:17:56+01:00
logce8c61b0fcb7e0610d4b39728b2d73ed10e762f6
tree205013fb60c2e44f153d3b5648fffd50636cc7ed
parent00481668671a8719627922a05a1c143f9d0409ed
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

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.

3 files changed, 35 insertions(+), 36 deletions(-)

lib/std/Target.zig+29-28
......@@ -1576,34 +1576,6 @@ pub const Cpu = struct {
15761576 };
15771577 }
15781578
1579 /// Returns whether this architecture supports `address_space`. If `context` is `null`, this
1580 /// function simply answers the general question of whether the architecture has any concept
1581 /// of `address_space`; if non-`null`, the function additionally checks whether
1582 /// `address_space` is valid in that context.
1583 pub fn supportsAddressSpace(
1584 arch: Arch,
1585 address_space: std.builtin.AddressSpace,
1586 context: ?std.builtin.AddressSpace.Context,
1587 ) bool {
1588 const is_nvptx = arch.isNvptx();
1589 const is_spirv = arch.isSpirV();
1590 const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
1591 return switch (address_space) {
1592 .generic => true,
1593 .fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer),
1594 .global, .local, .shared => is_gpu,
1595 .constant => is_gpu and (context == null or context == .constant),
1596 .param => is_nvptx,
1597 .input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
1598 // TODO this should also check how many flash banks the cpu has
1599 .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
1600
1601 // Propeller address spaces:
1602 .cog, .hub => arch == .propeller,
1603 .lut => arch == .propeller, // TODO: This should check for the `p2` CPU feature.
1604 };
1605 }
1606
16071579 /// Returns a name that matches the lib/std/target/* source file name.
16081580 pub fn genericName(arch: Arch) [:0]const u8 {
16091581 return switch (arch) {
......@@ -1999,6 +1971,35 @@ pub const Cpu = struct {
19991971 pub fn baseline(arch: Arch, os: Os) Cpu {
20001972 return Model.baseline(arch, os).toCpu(arch);
20011973 }
1974
1975 /// Returns whether this architecture supports `address_space`. If `context` is `null`, this
1976 /// function simply answers the general question of whether the architecture has any concept
1977 /// of `address_space`; if non-`null`, the function additionally checks whether
1978 /// `address_space` is valid in that context.
1979 pub fn supportsAddressSpace(
1980 cpu: Cpu,
1981 address_space: std.builtin.AddressSpace,
1982 context: ?std.builtin.AddressSpace.Context,
1983 ) bool {
1984 const arch = cpu.arch;
1985
1986 const is_nvptx = arch.isNvptx();
1987 const is_spirv = arch.isSpirV();
1988 const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
1989
1990 return switch (address_space) {
1991 .generic => true,
1992 .fs, .gs, .ss => (arch == .x86_64 or arch == .x86) and (context == null or context == .pointer),
1993 .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, // TODO this should also check how many flash banks the cpu has
1994 .cog, .hub => arch == .propeller,
1995 .lut => arch == .propeller and std.Target.propeller.featureSetHas(cpu.features, .p2),
1996
1997 .global, .local, .shared => is_gpu,
1998 .constant => is_gpu and (context == null or context == .constant),
1999 .param => is_nvptx,
2000 .input, .output, .uniform, .push_constant, .storage_buffer => is_spirv,
2001 };
2002 }
20022003};
20032004
20042005pub fn zigTriple(target: Target, allocator: Allocator) Allocator.Error![]u8 {
src/Sema.zig+2-3
......@@ -37244,9 +37244,8 @@ pub fn analyzeAsAddressSpace(
3724437244 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{ .simple = .@"addrspace" });
3724537245 const address_space = try sema.interpretBuiltinType(block, src, addrspace_val, std.builtin.AddressSpace);
3724637246 const target = pt.zcu.getTarget();
37247 const arch = target.cpu.arch;
3724837247
37249 if (!arch.supportsAddressSpace(address_space, ctx)) {
37248 if (!target.cpu.supportsAddressSpace(address_space, ctx)) {
3725037249 // TODO error messages could be made more elaborate here
3725137250 const entity = switch (ctx) {
3725237251 .function => "functions",
......@@ -37258,7 +37257,7 @@ pub fn analyzeAsAddressSpace(
3725837257 block,
3725937258 src,
3726037259 "{s} with address space '{s}' are not supported on {s}",
37261 .{ entity, @tagName(address_space), arch.genericName() },
37260 .{ entity, @tagName(address_space), target.cpu.arch.genericName() },
3726237261 );
3726337262 }
3726437263
src/target.zig+4-5
......@@ -442,12 +442,11 @@ pub fn addrSpaceCastIsValid(
442442 from: AddressSpace,
443443 to: AddressSpace,
444444) bool {
445 const arch = target.cpu.arch;
446 switch (arch) {
447 .x86_64, .x86 => return arch.supportsAddressSpace(from, null) and arch.supportsAddressSpace(to, null),
445 switch (target.cpu.arch) {
446 .x86_64, .x86 => return target.cpu.supportsAddressSpace(from, null) and target.cpu.supportsAddressSpace(to, null),
448447 .nvptx64, .nvptx, .amdgcn => {
449 const to_generic = arch.supportsAddressSpace(from, null) and to == .generic;
450 const from_generic = arch.supportsAddressSpace(to, null) and from == .generic;
448 const to_generic = target.cpu.supportsAddressSpace(from, null) and to == .generic;
449 const from_generic = target.cpu.supportsAddressSpace(to, null) and from == .generic;
451450 return to_generic or from_generic;
452451 },
453452 else => return from == .generic and to == .generic,