| ... | ... | @@ -540,27 +540,25 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz |
| 540 | 540 | node.context.maybeRefresh(); |
| 541 | 541 | } |
| 542 | 542 | |
| 543 | /// I have observed the CPU name reported by LLVM being incorrect. On |
| 544 | /// the SourceHut build services, LLVM 9.0 reports the CPU as "athlon-xp", |
| 545 | /// which is a 32-bit CPU, even though the system is 64-bit and the reported |
| 546 | /// CPU features include, among other things, +64bit. |
| 547 | /// So the strategy taken here is that we observe both reported CPU, and the |
| 548 | /// reported CPU features. The features are trusted more; but if the features |
| 549 | /// match exactly the features of the reported CPU, then we trust the reported CPU. |
| 543 | 550 | fn cpuFeaturesFromLLVM( |
| 544 | 551 | arch: Target.Arch, |
| 545 | 552 | llvm_cpu_name_z: ?[*:0]const u8, |
| 546 | 553 | llvm_cpu_features_opt: ?[*:0]const u8, |
| 547 | 554 | ) !Target.CpuFeatures { |
| 548 | | if (llvm_cpu_name_z) |cpu_name_z| { |
| 549 | | const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z); |
| 550 | | |
| 551 | | for (arch.allCpus()) |cpu| { |
| 552 | | const this_llvm_name = cpu.llvm_name orelse continue; |
| 553 | | if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { |
| 554 | | return Target.CpuFeatures{ .cpu = cpu }; |
| 555 | | } |
| 556 | | } |
| 557 | | } |
| 558 | | |
| 559 | 555 | var set = arch.baselineFeatures(); |
| 560 | 556 | const llvm_cpu_features = llvm_cpu_features_opt orelse return Target.CpuFeatures{ |
| 561 | 557 | .features = set, |
| 562 | 558 | }; |
| 563 | 559 | |
| 560 | const all_features = arch.allFeaturesList(); |
| 561 | |
| 564 | 562 | var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ","); |
| 565 | 563 | while (it.next()) |decorated_llvm_feat| { |
| 566 | 564 | var op: enum { |
| ... | ... | @@ -577,7 +575,7 @@ fn cpuFeaturesFromLLVM( |
| 577 | 575 | } else { |
| 578 | 576 | return error.InvalidLlvmCpuFeaturesFormat; |
| 579 | 577 | } |
| 580 | | for (arch.allFeaturesList()) |feature, index| { |
| 578 | for (all_features) |feature, index| { |
| 581 | 579 | const this_llvm_name = feature.llvm_name orelse continue; |
| 582 | 580 | if (mem.eql(u8, llvm_feat, this_llvm_name)) { |
| 583 | 581 | switch (op) { |
| ... | ... | @@ -588,6 +586,27 @@ fn cpuFeaturesFromLLVM( |
| 588 | 586 | } |
| 589 | 587 | } |
| 590 | 588 | } |
| 589 | |
| 590 | if (llvm_cpu_name_z) |cpu_name_z| { |
| 591 | const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z); |
| 592 | |
| 593 | for (arch.allCpus()) |cpu| { |
| 594 | const this_llvm_name = cpu.llvm_name orelse continue; |
| 595 | if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { |
| 596 | // Only trust the CPU if the reported features exactly match. |
| 597 | var populated_reported_features = set; |
| 598 | populated_reported_features.populateDependencies(all_features); |
| 599 | var populated_cpu_features = cpu.features; |
| 600 | populated_cpu_features.populateDependencies(all_features); |
| 601 | if (populated_reported_features.eql(populated_cpu_features)) { |
| 602 | return Target.CpuFeatures{ .cpu = cpu }; |
| 603 | } else { |
| 604 | return Target.CpuFeatures{ .features = set }; |
| 605 | } |
| 606 | } |
| 607 | } |
| 608 | } |
| 609 | |
| 591 | 610 | return Target.CpuFeatures{ .features = set }; |
| 592 | 611 | } |
| 593 | 612 | |