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.
This commit is contained in:
Andrew Kelley
2021-06-15 11:39:53 -07:00
parent 515d6430c0
commit 90c73d8768

View File

@@ -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