Have a look at src/Compilation.zig lines 6677-6726:
// The Clang assembler does not accept the list of CPU features like the
// compiler frontend does. Therefore we must hard-code the -m flags for
// all CPU features here.
switch (target.cpu.arch) {
.riscv32, .riscv32be, .riscv64, .riscv64be => {
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 + 1]u8 = undefined;
var march_index: usize = prefix_len;
@memcpy(march_buf[0..prefix.len], prefix);
if (target.cpu.has(.riscv, .e)) {
march_buf[march_index] = 'e';
} else {
march_buf[march_index] = 'i';
}
march_index += 1;
for (letters) |letter| {
if (target.cpu.has(.riscv, 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 (target.cpu.has(.riscv, .relax)) {
try argv.append("-mrelax");
} else {
try argv.append("-mno-relax");
}
if (target.cpu.has(.riscv, .save_restore)) {
try argv.append("-msave-restore");
} else {
try argv.append("-mno-save-restore");
}
},
You can set ZIG_VERBOSE_CC=1 environment variable to obtain the zig clang command line being used to attempt to build the assembly.
If you can figure out what flags are needed to be passed to correctly communicate the target, you’re 95% of the way to fixing this problem in the compiler.
I was compiling with llvm-mc before which just takes the list of extentions as comma seperated values . I assumed that’s what zig used under the hood
So the issue was it completely ignores those feature sets and we have to include them by just concatnating the feature set enum tagnames with _ in between