From eaea4e016c7537e173b4e2f9912853c90307a340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20=22xq=22=20Quei=C3=9Fner?= Date: Tue, 1 Oct 2024 21:13:14 +0200 Subject: [PATCH 1/2] Adds new cpu architectures propeller1 and propeller2. These cpu architectures allow targeting the Parallax Propeller 1 and Propeller 2, which are both very special microcontrollers with 512 registers and 8 cpu cores. Resolves #21559 --- lib/std/Target.zig | 30 ++++++++++++++++++++++++++++++ lib/std/Target/propeller.zig | 21 +++++++++++++++++++++ lib/std/builtin.zig | 11 +++++++++++ src/Sema.zig | 3 +++ src/Type.zig | 1 + src/Zcu.zig | 2 ++ src/codegen/llvm.zig | 3 +++ src/codegen/spirv.zig | 3 +++ src/target.zig | 2 ++ 9 files changed, 76 insertions(+) create mode 100644 lib/std/Target/propeller.zig diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 146af1cf9f0c..7d864ae6bbd9 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -647,6 +647,7 @@ pub const ve = @import("Target/ve.zig"); pub const wasm = @import("Target/wasm.zig"); pub const x86 = @import("Target/x86.zig"); pub const xtensa = @import("Target/xtensa.zig"); +pub const propeller = @import("Target/propeller.zig"); pub const Abi = enum { none, @@ -880,6 +881,8 @@ pub fn toElfMachine(target: Target) std.elf.EM { .ve, .wasm32, .wasm64, + .propeller1, + .propeller2, => .NONE, }; } @@ -932,6 +935,8 @@ pub fn toCoffMachine(target: Target) std.coff.MachineType { .wasm64, .xcore, .xtensa, + .propeller1, + .propeller2, => .UNKNOWN, }; } @@ -1163,6 +1168,8 @@ pub const Cpu = struct { x86_64, xcore, xtensa, + propeller1, + propeller2, // LLVM tags deliberately omitted: // - aarch64_32 @@ -1300,6 +1307,14 @@ pub const Cpu = struct { }; } + /// Returns if the architecture is a Parallax propeller architecture. + pub inline fn isPropeller(arch: Arch) bool { + return switch (arch) { + .propeller1, .propeller2 => true, + else => false, + }; + } + pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model { for (arch.allCpuModels()) |cpu| { if (std.mem.eql(u8, cpu_name, cpu.name)) { @@ -1344,6 +1359,8 @@ pub const Cpu = struct { .loongarch32, .loongarch64, .arc, + .propeller1, + .propeller2, => .little, .armeb, @@ -1376,6 +1393,10 @@ pub const Cpu = struct { .input, .output, .uniform => 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.isPropeller(), + .lut => (arch == .propeller2), }; } @@ -1396,6 +1417,7 @@ pub const Cpu = struct { .nvptx, .nvptx64 => "nvptx", .wasm32, .wasm64 => "wasm", .spirv, .spirv32, .spirv64 => "spirv", + .propeller1, .propeller2 => "propeller", else => @tagName(arch), }; } @@ -1799,6 +1821,8 @@ pub const DynamicLinker = struct { .spirv, .spirv32, .spirv64, + .propeller1, + .propeller2, => none, // TODO go over each item in this list and either move it to the above list, or @@ -1909,6 +1933,8 @@ pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 { .spirv32, .loongarch32, .xtensa, + .propeller1, + .propeller2, => 32, .aarch64, @@ -2413,6 +2439,8 @@ pub fn cTypeAlignment(target: Target, c_type: CType) u16 { .kalimba, .spu_2, .xtensa, + .propeller1, + .propeller2, => 4, .amdgcn, @@ -2516,6 +2544,8 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 { .kalimba, .spu_2, .xtensa, + .propeller1, + .propeller2, => 4, .arc, diff --git a/lib/std/Target/propeller.zig b/lib/std/Target/propeller.zig new file mode 100644 index 000000000000..bc49f471295f --- /dev/null +++ b/lib/std/Target/propeller.zig @@ -0,0 +1,21 @@ + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum {}; + +pub const featureSet = CpuFeature.FeatureSetFns(Feature).featureSet; +pub const featureSetHas = CpuFeature.FeatureSetFns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; + +pub const all_features: [0]CpuFeature = .{}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = null, + .features = featureSet(&[_]Feature{}), + }; +}; diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index f2cd78160f9d..499858662d12 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -236,6 +236,17 @@ pub const AddressSpace = enum(u5) { flash3, flash4, flash5, + + // Propeller address spaces. + + /// This address space only addresses the cog-local ram. + cog, + + /// This address space only addresses shared hub ram. + hub, + + /// This address space only addresses the "lookup" ram + lut, }; /// This data structure is used by the Zig language code generation and diff --git a/src/Sema.zig b/src/Sema.zig index ea409be6ab37..1b9657ce9d07 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -37672,6 +37672,9 @@ pub fn analyzeAsAddressSpace( .constant => is_gpu and (ctx == .constant), // TODO this should also check how many flash banks the cpu has .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr, + + .cog, .hub => arch.isPropeller(), + .lut => (arch == .propeller2), }; if (!supported) { diff --git a/src/Type.zig b/src/Type.zig index 19ddf6dfedf3..808c8cfdb3ce 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -1641,6 +1641,7 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 { .avr => 1, .msp430 => 2, .xcore => 4, + .propeller1, .propeller2 => 4, .arm, .armeb, diff --git a/src/Zcu.zig b/src/Zcu.zig index 2a52bf4bcfd7..641c7fc8802e 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -3000,6 +3000,8 @@ pub fn atomicPtrAlignment( .spirv32, .loongarch32, .xtensa, + .propeller1, + .propeller2, => 32, .amdgcn, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index f4003347871c..e10ad425e333 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -88,7 +88,10 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { .kalimba, .spu_2, + .propeller1, + .propeller2, => unreachable, // Gated by hasLlvmSupport(). + }; try llvm_triple.appendSlice(llvm_arch); diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index dc45b269312c..164367207acf 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1856,6 +1856,9 @@ const NavGen = struct { .flash3, .flash4, .flash5, + .cog, + .lut, + .hub, => unreachable, }; } diff --git a/src/target.zig b/src/target.zig index 6348543f9486..0af7afed465d 100644 --- a/src/target.zig +++ b/src/target.zig @@ -168,6 +168,8 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool { // No LLVM backend exists. .kalimba, .spu_2, + .propeller1, + .propeller2, => false, }; } From 55b0813cb946cfba67cca5113e9d44efcdeedcd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20=22xq=22=20Quei=C3=9Fner?= Date: Wed, 2 Oct 2024 11:27:32 +0200 Subject: [PATCH 2/2] Adjusts code according to review comments. * Adds std.elf.EM.PROPELLER and std.elf.EM.PROPELLER2 * Fixes missing switch prongs in src/codegen/llvm.zig * Fixes order in std.Target.Arch --- lib/std/Target.zig | 9 +++++---- lib/std/Target/propeller.zig | 1 - lib/std/builtin.zig | 2 +- lib/std/elf.zig | 8 ++++++++ src/codegen/llvm.zig | 6 ++++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 7d864ae6bbd9..488a0b0647ad 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -873,6 +873,9 @@ pub fn toElfMachine(target: Target) std.elf.EM { .xcore => .XCORE, .xtensa => .XTENSA, + .propeller1 => .PROPELLER, + .propeller2 => .PROPELLER2, + .nvptx, .nvptx64, .spirv, @@ -881,8 +884,6 @@ pub fn toElfMachine(target: Target) std.elf.EM { .ve, .wasm32, .wasm64, - .propeller1, - .propeller2, => .NONE, }; } @@ -1152,6 +1153,8 @@ pub const Cpu = struct { powerpcle, powerpc64, powerpc64le, + propeller1, + propeller2, riscv32, riscv64, s390x, @@ -1168,8 +1171,6 @@ pub const Cpu = struct { x86_64, xcore, xtensa, - propeller1, - propeller2, // LLVM tags deliberately omitted: // - aarch64_32 diff --git a/lib/std/Target/propeller.zig b/lib/std/Target/propeller.zig index bc49f471295f..929e3ff74c81 100644 --- a/lib/std/Target/propeller.zig +++ b/lib/std/Target/propeller.zig @@ -1,4 +1,3 @@ - const std = @import("../std.zig"); const CpuFeature = std.Target.Cpu.Feature; const CpuModel = std.Target.Cpu.Model; diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 499858662d12..82fa1f9f6795 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -240,7 +240,7 @@ pub const AddressSpace = enum(u5) { // Propeller address spaces. /// This address space only addresses the cog-local ram. - cog, + cog, /// This address space only addresses shared hub ram. hub, diff --git a/lib/std/elf.zig b/lib/std/elf.zig index d92973c314cb..1c6e581f04df 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -1552,6 +1552,14 @@ pub const EM = enum(u16) { /// Adapteva's Epiphany architecture ADAPTEVA_EPIPHANY = 0x1223, + /// Parallax Propeller (P1) + /// This value is an unofficial ELF value used in: https://github.com/parallaxinc/propgcc + PROPELLER = 0x5072, + + /// Parallax Propeller 2 (P2) + /// This value is an unofficial ELF value used in: https://github.com/ne75/llvm-project + PROPELLER2 = 300, + _, }; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e10ad425e333..846c2754f0ca 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -91,7 +91,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { .propeller1, .propeller2, => unreachable, // Gated by hasLlvmSupport(). - + }; try llvm_triple.appendSlice(llvm_arch); @@ -285,7 +285,7 @@ pub fn targetArch(arch_tag: std.Target.Cpu.Arch) llvm.ArchType { .wasm32 => .wasm32, .wasm64 => .wasm64, .ve => .ve, - .spu_2 => .UnknownArch, + .propeller1, .propeller2, .spu_2 => .UnknownArch, }; } @@ -12717,6 +12717,8 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void { // LLVM does does not have a backend for these. .kalimba, .spu_2, + .propeller1, + .propeller2, => unreachable, } }