diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-06-15 11:39:53 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-06-15 17:12:22 -0400 |
| commit | 90c73d8768bd51c84a5bf3d589d31abce6d93d37 (patch) | |
| tree | 3a8cd89a878209178a2c8561d15ef33cb6fb118e /src | |
| parent | 515d6430c0298daf304e48b46e6b43802bbfdab4 (diff) | |
| download | zig-90c73d8768bd51c84a5bf3d589d31abce6d93d37.tar.gz zig-90c73d8768bd51c84a5bf3d589d31abce6d93d37.zip | |
fix RISC-V assembly CPU features
Previously, Zig did not properly communicate the target CPU features for
RISC-V to clang assembler, because Clang has a different way to pass CPU
features for C code and for assembly code. This commit makes Zig pass a
RISC-V -march flag in order to communicate CPU features to Clang when
compiling assembly files.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 00c5937394..dc5fcbf361 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3004,11 +3004,50 @@ pub fn addCCArgs( // all CPU features here. switch (target.cpu.arch) { .riscv32, .riscv64 => { + const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature }; + const letters = [_]RvArchFeat{ + .{ .char = 'm', .feat = .m }, + .{ .char = 'a', .feat = .a }, + .{ .char = 'f', .feat = .f }, + .{ .char = 'd', .feat = .d }, + .{ .char = 'c', .feat = .c }, + }; + const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32"; + const prefix_len = 4; + assert(prefix.len == prefix_len); + var march_buf: [prefix_len + letters.len]u8 = undefined; + var march_index: usize = prefix_len; + mem.copy(u8, &march_buf, prefix); + + if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) { + march_buf[march_index] = 'e'; + } else { + march_buf[march_index] = 'i'; + } + march_index += 1; + + for (letters) |letter| { + if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) { + march_buf[march_index] = letter.char; + march_index += 1; + } + } + + const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{ + march_buf[0..march_index], + }); + try argv.append(march_arg); + if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { try argv.append("-mrelax"); } else { try argv.append("-mno-relax"); } + if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) { + try argv.append("-msave-restore"); + } else { + try argv.append("-mno-save-restore"); + } }, else => { // TODO |
