From 7c74edec8d7d97677033d8a688e02ee32d82ab43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Quei=C3=9Fner?= Date: Fri, 4 Oct 2024 22:53:28 +0200 Subject: [PATCH] Adds new cpu architectures propeller1 and propeller2. (#21563) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * 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 --------- Co-authored-by: Felix "xq" Queißner --- lib/std/Target.zig | 31 +++++++++++++++++++++++++++++++ lib/std/Target/propeller.zig | 20 ++++++++++++++++++++ lib/std/builtin.zig | 11 +++++++++++ lib/std/elf.zig | 8 ++++++++ src/Sema.zig | 3 +++ src/Type.zig | 1 + src/Zcu.zig | 2 ++ src/codegen/llvm.zig | 7 ++++++- src/codegen/spirv.zig | 3 +++ src/target.zig | 2 ++ 10 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 lib/std/Target/propeller.zig diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 10e0de169e..5685887e5d 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -648,6 +648,7 @@ pub const wasm = @import("Target/wasm.zig"); pub const x86 = @import("Target/x86.zig"); pub const xcore = @import("Target/xcore.zig"); pub const xtensa = @import("Target/xtensa.zig"); +pub const propeller = @import("Target/propeller.zig"); pub const Abi = enum { none, @@ -882,6 +883,9 @@ pub fn toElfMachine(target: Target) std.elf.EM { .xcore => .XCORE, .xtensa => .XTENSA, + .propeller1 => .PROPELLER, + .propeller2 => .PROPELLER2, + .nvptx, .nvptx64, .spirv, @@ -941,6 +945,8 @@ pub fn toCoffMachine(target: Target) std.coff.MachineType { .wasm64, .xcore, .xtensa, + .propeller1, + .propeller2, => .UNKNOWN, }; } @@ -1156,6 +1162,8 @@ pub const Cpu = struct { powerpcle, powerpc64, powerpc64le, + propeller1, + propeller2, riscv32, riscv64, s390x, @@ -1309,6 +1317,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)) { @@ -1353,6 +1369,8 @@ pub const Cpu = struct { .loongarch32, .loongarch64, .arc, + .propeller1, + .propeller2, => .little, .armeb, @@ -1385,6 +1403,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), }; } @@ -1405,6 +1427,7 @@ pub const Cpu = struct { .nvptx, .nvptx64 => "nvptx", .wasm32, .wasm64 => "wasm", .spirv, .spirv32, .spirv64 => "spirv", + .propeller1, .propeller2 => "propeller", else => @tagName(arch), }; } @@ -1819,6 +1842,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 @@ -1928,6 +1953,8 @@ pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 { .spirv32, .loongarch32, .xtensa, + .propeller1, + .propeller2, => 32, .aarch64, @@ -2432,6 +2459,8 @@ pub fn cTypeAlignment(target: Target, c_type: CType) u16 { .kalimba, .spu_2, .xtensa, + .propeller1, + .propeller2, => 4, .amdgcn, @@ -2536,6 +2565,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 0000000000..929e3ff74c --- /dev/null +++ b/lib/std/Target/propeller.zig @@ -0,0 +1,20 @@ +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 f2cd78160f..82fa1f9f67 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/lib/std/elf.zig b/lib/std/elf.zig index d948e8fcc5..792694dffb 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -1628,6 +1628,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/Sema.zig b/src/Sema.zig index ea409be6ab..1b9657ce9d 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 19ddf6dfed..808c8cfdb3 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 2a52bf4bcf..641c7fc880 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 9520f17a4b..21685a5ff8 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); @@ -281,7 +284,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, }; } @@ -12714,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, } } diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index dc45b26931..164367207a 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 7667303704..5847d3d8cd 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, }; }