authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-10-05 13:49:05+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-05 13:49:05+02:00
logd23db9427b82d7dc798442accf34729c16e92f2d
tree8d95d6b3af2d3ead34a2a1410ddf669cf604316c
parent73de620ad50121bacb0b9b376efd50b5444485b8
parent85bf1e2b1fdc960e7e612307aecaac3a125fdfe6
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21574 from alexrp/llvm-sub-arch

`llvm`: Implement sub-architecture translation in `targetTriple()`.

1 files changed, 74 insertions(+), 4 deletions(-)

src/codegen/llvm.zig+74-4
...@@ -37,10 +37,20 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;...@@ -37,10 +37,20 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
3737
38const Error = error{ OutOfMemory, CodegenFail };38const Error = error{ OutOfMemory, CodegenFail };
3939
40fn subArchName(features: std.Target.Cpu.Feature.Set, arch: anytype, mappings: anytype) ?[]const u8 {
41 inline for (mappings) |mapping| {
42 if (arch.featureSetHas(features, mapping[0])) return mapping[1];
43 }
44
45 return null;
46}
47
40pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {48pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
41 var llvm_triple = std.ArrayList(u8).init(allocator);49 var llvm_triple = std.ArrayList(u8).init(allocator);
42 defer llvm_triple.deinit();50 defer llvm_triple.deinit();
4351
52 const features = target.cpu.features;
53
44 const llvm_arch = switch (target.cpu.arch) {54 const llvm_arch = switch (target.cpu.arch) {
45 .arm => "arm",55 .arm => "arm",
46 .armeb => "armeb",56 .armeb => "armeb",
...@@ -55,10 +65,11 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {...@@ -55,10 +65,11 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
55 .loongarch32 => "loongarch32",65 .loongarch32 => "loongarch32",
56 .loongarch64 => "loongarch64",66 .loongarch64 => "loongarch64",
57 .m68k => "m68k",67 .m68k => "m68k",
58 .mips => "mips",68 // MIPS sub-architectures are a bit irregular, so we handle them manually here.
59 .mipsel => "mipsel",69 .mips => if (std.Target.mips.featureSetHas(features, .mips32r6)) "mipsisa32r6" else "mips",
60 .mips64 => "mips64",70 .mipsel => if (std.Target.mips.featureSetHas(features, .mips32r6)) "mipsisa32r6el" else "mipsel",
61 .mips64el => "mips64el",71 .mips64 => if (std.Target.mips.featureSetHas(features, .mips64r6)) "mipsisa64r6" else "mips64",
72 .mips64el => if (std.Target.mips.featureSetHas(features, .mips64r6)) "mipsisa64r6el" else "mips64el",
62 .msp430 => "msp430",73 .msp430 => "msp430",
63 .powerpc => "powerpc",74 .powerpc => "powerpc",
64 .powerpcle => "powerpcle",75 .powerpcle => "powerpcle",
...@@ -93,8 +104,67 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {...@@ -93,8 +104,67 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
93 => unreachable, // Gated by hasLlvmSupport().104 => unreachable, // Gated by hasLlvmSupport().
94105
95 };106 };
107
96 try llvm_triple.appendSlice(llvm_arch);108 try llvm_triple.appendSlice(llvm_arch);
97109
110 const llvm_sub_arch: ?[]const u8 = switch (target.cpu.arch) {
111 .arm, .armeb, .thumb, .thumbeb => subArchName(features, std.Target.arm, .{
112 .{ .v4t, "v4t" },
113 .{ .v5t, "v5t" },
114 .{ .v5te, "v5te" },
115 .{ .v5tej, "v5tej" },
116 .{ .v6, "v6" },
117 .{ .v6k, "v6k" },
118 .{ .v6kz, "v6kz" },
119 .{ .v6m, "v6m" },
120 .{ .v6t2, "v6t2" },
121 // v7k and v7s imply v7a so they have to be tested first.
122 .{ .v7k, "v7k" },
123 .{ .v7s, "v7s" },
124 .{ .v7a, "v7a" },
125 .{ .v7em, "v7em" },
126 .{ .v7m, "v7m" },
127 .{ .v7r, "v7r" },
128 .{ .v7ve, "v7ve" },
129 .{ .v8a, "v8a" },
130 .{ .v8_1a, "v8.1a" },
131 .{ .v8_2a, "v8.2a" },
132 .{ .v8_3a, "v8.3a" },
133 .{ .v8_4a, "v8.4a" },
134 .{ .v8_5a, "v8.5a" },
135 .{ .v8_6a, "v8.6a" },
136 .{ .v8_7a, "v8.7a" },
137 .{ .v8_8a, "v8.8a" },
138 .{ .v8_9a, "v8.9a" },
139 .{ .v8m, "v8m.base" },
140 .{ .v8m_main, "v8m.main" },
141 .{ .v8_1m_main, "v8.1m.main" },
142 .{ .v8r, "v8r" },
143 .{ .v9a, "v9a" },
144 .{ .v9_1a, "v9.1a" },
145 .{ .v9_2a, "v9.2a" },
146 .{ .v9_3a, "v9.3a" },
147 .{ .v9_4a, "v9.4a" },
148 .{ .v9_5a, "v9.5a" },
149 }),
150 .powerpc => subArchName(features, std.Target.powerpc, .{
151 .{ .spe, "spe" },
152 }),
153 .spirv => subArchName(features, std.Target.spirv, .{
154 .{ .v1_5, "1.5" },
155 }),
156 .spirv32, .spirv64 => subArchName(features, std.Target.spirv, .{
157 .{ .v1_5, "1.5" },
158 .{ .v1_4, "1.4" },
159 .{ .v1_3, "1.3" },
160 .{ .v1_2, "1.2" },
161 .{ .v1_1, "1.1" },
162 }),
163 else => null,
164 };
165
166 if (llvm_sub_arch) |sub| try llvm_triple.appendSlice(sub);
167
98 // Unlike CPU backends, GPU backends actually care about the vendor tag.168 // Unlike CPU backends, GPU backends actually care about the vendor tag.
99 try llvm_triple.appendSlice(switch (target.cpu.arch) {169 try llvm_triple.appendSlice(switch (target.cpu.arch) {
100 .amdgcn => if (target.os.tag == .mesa3d) "-mesa-" else "-amd-",170 .amdgcn => if (target.os.tag == .mesa3d) "-mesa-" else "-amd-",