support -mcpu=baseline, both in stage1 and stage2

See e381a42de9 for more details.
This is set up so that if we wish to make "baseline" depend on the
OS in the future, it is possible to do that.
This commit is contained in:
Andrew Kelley 2020-02-20 18:31:17 -05:00
parent 33c69d5cb6
commit 0f016b368d
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
6 changed files with 44 additions and 33 deletions

View File

@ -726,8 +726,7 @@ pub const Target = union(enum) {
/// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
/// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
/// to remove from the set.
/// The default value of `null` means to use the "baseline" feature set.
cpu: ?[]const u8 = null,
cpu_features: []const u8 = "baseline",
};
pub fn parse(args: ParseOptions) !Target {
@ -742,23 +741,29 @@ pub const Target = union(enum) {
const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os);
const all_features = arch.allFeaturesList();
const cpu: Cpu = if (args.cpu) |cpu_text| blk: {
var index: usize = 0;
while (index < cpu_text.len and cpu_text[index] != '+' and cpu_text[index] != '-') {
index += 1;
}
const cpu_name = cpu_text[0..index];
var index: usize = 0;
while (index < args.cpu_features.len and
args.cpu_features[index] != '+' and
args.cpu_features[index] != '-')
{
index += 1;
}
const cpu_name = args.cpu_features[0..index];
const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: {
const cpu_model = try arch.parseCpuModel(cpu_name);
var set = cpu_model.features;
while (index < cpu_text.len) {
const op = cpu_text[index];
while (index < args.cpu_features.len) {
const op = args.cpu_features[index];
index += 1;
const start = index;
while (index < cpu_text.len and cpu_text[index] != '+' and cpu_text[index] != '-') {
while (index < args.cpu_features.len and
args.cpu_features[index] != '+' and
args.cpu_features[index] != '-')
{
index += 1;
}
const feature_name = cpu_text[start..index];
const feature_name = args.cpu_features[start..index];
for (all_features) |feature, feat_index_usize| {
const feat_index = @intCast(Cpu.Feature.Set.Index, feat_index_usize);
if (mem.eql(u8, feature_name, feature.name)) {
@ -779,8 +784,7 @@ pub const Target = union(enum) {
.model = cpu_model,
.features = set,
};
} else Cpu.baseline(arch);
};
var cross = Cross{
.cpu = cpu,
.os = os,

View File

@ -675,8 +675,8 @@ fn stage2TargetParse(
) !void {
const target: Target = if (zig_triple_oz) |zig_triple_z| blk: {
const zig_triple = mem.toSliceConst(u8, zig_triple_z);
const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null;
break :blk try Target.parse(.{ .arch_os_abi = zig_triple, .cpu = mcpu });
const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline";
break :blk try Target.parse(.{ .arch_os_abi = zig_triple, .cpu_features = mcpu });
} else Target.Native;
try stage1_target.fromTarget(target);

View File

@ -97,10 +97,20 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons
if (zig_triple == nullptr) {
get_native_target(target);
target->llvm_cpu_name = ZigLLVMGetHostCPUName();
target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
target->builtin_str = "Target.Cpu.baseline(arch);\n";
target->cache_hash = "native\n\n";
if (mcpu == nullptr) {
target->llvm_cpu_name = ZigLLVMGetHostCPUName();
target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
target->builtin_str = "Target.Cpu.baseline(arch);\n";
target->cache_hash = "native\n\n";
} else if (strcmp(mcpu, "baseline") == 0) {
target->llvm_cpu_name = "";
target->llvm_cpu_features = "";
target->builtin_str = "Target.Cpu.baseline(arch);\n";
target->cache_hash = "baseline\n\n";
} else {
const char *msg = "stage0 can't handle CPU/features in the target";
stage2_panic(msg, strlen(msg));
}
} else {
// first initialize all to zero
*target = {};
@ -135,15 +145,14 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons
target->abi = target_default_abi(target->arch, target->os);
}
if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) {
const char *msg = "stage0 can't handle CPU/features in the target";
stage2_panic(msg, strlen(msg));
}
target->builtin_str = "Target.Cpu.baseline(arch);\n";
target->cache_hash = "\n\n";
}
if (mcpu != nullptr) {
const char *msg = "stage0 can't handle CPU/features in the target";
stage2_panic(msg, strlen(msg));
}
return ErrorNone;
}

View File

@ -350,8 +350,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
});
tc.target = Target{
.Cross = .{
.arch = .wasm32,
.cpu_features = Target.Arch.wasm32.getBaselineCpuFeatures(),
.cpu = Target.Cpu.baseline(.wasm32),
.os = .wasi,
.abi = .none,
},

View File

@ -135,13 +135,13 @@ const test_targets = blk: {
TestTarget{
.target = Target.parse(.{
.arch_os_abi = "arm-linux-none",
.cpu = "generic+v8a",
.cpu_features = "generic+v8a",
}) catch unreachable,
},
TestTarget{
.target = Target.parse(.{
.arch_os_abi = "arm-linux-musleabihf",
.cpu = "generic+v8a",
.cpu_features = "generic+v8a",
}) catch unreachable,
.link_libc = true,
},
@ -149,7 +149,7 @@ const test_targets = blk: {
//TestTarget{
// .target = Target.parse(.{
// .arch_os_abi = "arm-linux-gnueabihf",
// .cpu = "generic+v8a",
// .cpu_features = "generic+v8a",
// }) catch unreachable,
// .link_libc = true,
//},
@ -449,7 +449,7 @@ pub fn addPkgTests(
const ArchTag = @TagType(builtin.Arch);
if (test_target.disable_native and
test_target.target.getOs() == builtin.os and
@as(ArchTag, test_target.target.getArch()) == @as(ArchTag, builtin.arch))
test_target.target.getArch() == builtin.arch)
{
continue;
}

View File

@ -1095,10 +1095,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.addWithTarget("Calling convention", tests.Target{
.Cross = .{
.cpu = Target.Cpu.baseline(.i386),
.os = .linux,
.arch = .i386,
.abi = .none,
.cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
},
},
\\void __attribute__((fastcall)) foo1(float *a);