| author | |
| committer | |
| log | 93316d6e613cbcf0b1f94da42bffdf9eac3223de |
| tree | 7419c1d4910c58c5dddf35f661c3133c56eacfde |
| parent | 03422925b127a8d369fc82ce333e2d77366c3849 |
| signature | Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM |
5 files changed, 165 insertions(+), 163 deletions(-)
lib/std/zig/target.zig+158| ... | ... | @@ -537,6 +537,164 @@ pub fn compilerRtFloatAbi(target: *const std.Target, bits: u16) std.Target.Abi.F |
| 537 | 537 | return .hard; |
| 538 | 538 | } |
| 539 | 539 | |
| 540 | fn supportedCompatArch(host: *const std.Target, arch: std.Target.Cpu.Arch) bool { | |
| 541 | // aarch64-freebsd and aarch64-linux can technically run 32-bit ARM binaries, but that depends | |
| 542 | // on AArch32 support in the CPU. Since modern AArch64 CPUs have largely dropped this support, | |
| 543 | // avoid reporting compatibility for 32-bit here since we'd just build a bunch of test binaries | |
| 544 | // that never get run anyway. This added almost an hour's worth of useless work to aarch64-linux | |
| 545 | // CI, for example. | |
| 546 | // | |
| 547 | // riscv64-linux and riscv64-netbsd similarly support 32-bit binaries. However, this requires a | |
| 548 | // very recent kernel and for the kernel feature to be enabled. Additionally, contemporary | |
| 549 | // RISC-V hardware is just too slow to justify building the 32-bit binaries. | |
| 550 | return switch (host.os.tag) { | |
| 551 | .illumos => switch (host.cpu.arch) { | |
| 552 | .x86_64 => arch == .x86, | |
| 553 | else => false, | |
| 554 | }, | |
| 555 | .linux => switch (host.cpu.arch) { | |
| 556 | .mips64 => arch == .mips, | |
| 557 | .mips64el => arch == .mipsel, | |
| 558 | .powerpc64 => arch == .powerpc, | |
| 559 | .sparc64 => arch == .sparc, | |
| 560 | .x86_64 => arch == .x86, | |
| 561 | else => false, | |
| 562 | }, | |
| 563 | .netbsd => switch (host.cpu.arch) { | |
| 564 | .sparc64 => arch == .sparc, | |
| 565 | .x86_64 => arch == .x86, | |
| 566 | else => false, | |
| 567 | }, | |
| 568 | .windows => switch (host.cpu.arch) { | |
| 569 | .x86_64 => arch == .x86, | |
| 570 | else => false, | |
| 571 | }, | |
| 572 | else => false, | |
| 573 | }; | |
| 574 | } | |
| 575 | ||
| 576 | /// Intended for test code to determine whether it makes sense to run a test for a particular target | |
| 577 | /// on the host. This is not an objective check; it is best-effort and also makes subjective | |
| 578 | /// judgements for some targets. | |
| 579 | pub fn isNative(query: *const std.Target.Query, target: *const std.Target, host: *const std.Target) bool { | |
| 580 | if (query.isNative()) return true; | |
| 581 | ||
| 582 | if (target.cpu.arch != host.cpu.arch and !supportedCompatArch(host, target.cpu.arch)) | |
| 583 | return false; | |
| 584 | ||
| 585 | if (target.os.tag != host.os.tag) | |
| 586 | return false; | |
| 587 | ||
| 588 | // This check is really only necessary for the case where `host.cpu.arch.isAarch64()` and | |
| 589 | // `target.cpu.arch.isArm()`. As they are wholly separate `std.Target` families with their own | |
| 590 | // feature bits, the logic below would produce complete nonsense. | |
| 591 | // | |
| 592 | // This does mean that we aren't actually checking feature compatibility between these two | |
| 593 | // families even though we should. That's not a problem currently, but in the future, we may | |
| 594 | // need to add a special code path just for this specific case... | |
| 595 | if (target.cpu.arch.family() != host.cpu.arch.family()) | |
| 596 | return true; | |
| 597 | ||
| 598 | // Remove features that don't actually affect compatibility. | |
| 599 | const irrelevant: std.Target.Cpu.Feature.Set = switch (host.cpu.arch) { | |
| 600 | .x86_64 => std.Target.x86.featureSet(&.{ | |
| 601 | .@"16bit_mode", | |
| 602 | .@"32bit_mode", | |
| 603 | .@"64bit", | |
| 604 | .false_deps_bls, | |
| 605 | .false_deps_compress, | |
| 606 | .false_deps_expand, | |
| 607 | .false_deps_getmant, | |
| 608 | .false_deps_lzcnt, | |
| 609 | .false_deps_mulc, | |
| 610 | .false_deps_mullq, | |
| 611 | .false_deps_perm, | |
| 612 | .false_deps_popcnt, | |
| 613 | .false_deps_range, | |
| 614 | .false_deps_tzcnt, | |
| 615 | .fast_11bytenop, | |
| 616 | .fast_15bytenop, | |
| 617 | .fast_7bytenop, | |
| 618 | .fast_bextr, | |
| 619 | .fast_dpwssd, | |
| 620 | .fast_gather, | |
| 621 | .fast_hops, | |
| 622 | .fast_imm16, | |
| 623 | .fast_lzcnt, | |
| 624 | .fast_movbe, | |
| 625 | .fast_scalar_fsqrt, | |
| 626 | .fast_scalar_shift_masks, | |
| 627 | .fast_shld_rotate, | |
| 628 | .fast_variable_crosslane_shuffle, | |
| 629 | .fast_variable_perlane_shuffle, | |
| 630 | .fast_vector_fsqrt, | |
| 631 | .fast_vector_shift_masks, | |
| 632 | .faster_shift_than_shuffle, | |
| 633 | .no_bypass_delay, | |
| 634 | .no_bypass_delay_blend, | |
| 635 | .no_bypass_delay_mov, | |
| 636 | .no_bypass_delay_shuffle, | |
| 637 | .prefer_128_bit, | |
| 638 | .prefer_256_bit, | |
| 639 | .prefer_legacy_setcc, | |
| 640 | .prefer_mask_registers, | |
| 641 | .prefer_movmsk_over_vtest, | |
| 642 | .prefer_ndd_mem, | |
| 643 | .prefer_no_gather, | |
| 644 | .prefer_no_scatter, | |
| 645 | .slow_3ops_lea, | |
| 646 | .slow_incdec, | |
| 647 | .slow_indirect_call, | |
| 648 | .slow_lea, | |
| 649 | .slow_pmaddwd, | |
| 650 | .slow_pmulld, | |
| 651 | .slow_pmullq, | |
| 652 | .slow_shld, | |
| 653 | .slow_two_mem_ops, | |
| 654 | .slow_unaligned_mem_16, | |
| 655 | .slow_unaligned_mem_32, | |
| 656 | }), | |
| 657 | .aarch64, .aarch64_be => std.Target.aarch64.featureSet(&.{ | |
| 658 | .addr_lsl_slow_14, | |
| 659 | .align_cmp_csel_pairs, | |
| 660 | .alu_lsl_fast, | |
| 661 | .avoid_ldapur, | |
| 662 | .disable_fast_inc_vl, | |
| 663 | .exynos_cheap_as_move, | |
| 664 | .fast_ld1_single, | |
| 665 | .fixed_load_latency_4, | |
| 666 | .fuse_address, | |
| 667 | .fuse_addsub_2reg_const1, | |
| 668 | .fuse_adrp_add, | |
| 669 | .fuse_aes, | |
| 670 | .fuse_arith_logic, | |
| 671 | .fuse_crypto_eor, | |
| 672 | .fuse_csel, | |
| 673 | .fuse_cset, | |
| 674 | .fuse_fcsel, | |
| 675 | .fuse_literals, | |
| 676 | .has_limited_64bit_vector_mul_bandwidth, | |
| 677 | .predictable_select_expensive, | |
| 678 | .slow_misaligned_128store, | |
| 679 | .slow_paired_128, | |
| 680 | .slow_strqro_store, | |
| 681 | .use_experimental_zeroing_pseudos, | |
| 682 | .use_fixed_over_scalable_if_equal_cost, | |
| 683 | .use_postra_scheduler, | |
| 684 | .use_reciprocal_square_root, | |
| 685 | .use_wzr_to_vec_move, | |
| 686 | }), | |
| 687 | else => .empty, | |
| 688 | }; | |
| 689 | var set = target.cpu.features; | |
| 690 | set.removeFeatureSet(irrelevant); | |
| 691 | ||
| 692 | if (!host.cpu.features.isSuperSetOf(set)) | |
| 693 | return false; | |
| 694 | ||
| 695 | return true; | |
| 696 | } | |
| 697 | ||
| 540 | 698 | const std = @import("std"); |
| 541 | 699 | const assert = std.debug.assert; |
| 542 | 700 | const Allocator = std.mem.Allocator; |
test/src/Cases.zig+1-1| ... | ... | @@ -495,7 +495,7 @@ pub fn lowerToBuildSteps( |
| 495 | 495 | |
| 496 | 496 | if (case.case.? == .Error and options.skip_compile_errors) continue; |
| 497 | 497 | |
| 498 | if (options.skip_non_native and !@import("../tests.zig").isNative(&case.target, &b.graph.host.result)) | |
| 498 | if (options.skip_non_native and !std.zig.target.isNative(&case.target.query, &case.target.result, &b.graph.host.result)) | |
| 499 | 499 | continue; |
| 500 | 500 | |
| 501 | 501 | if (options.skip_spirv and case.target.query.cpu_arch != null and case.target.query.cpu_arch.?.isSpirV()) continue; |
test/src/ErrorTrace.zig+1-1| ... | ... | @@ -385,7 +385,7 @@ pub fn addCases(self: *ErrorTrace) void { |
| 385 | 385 | |
| 386 | 386 | if (!self.options.test_extra_targets and params.extra_target) continue; |
| 387 | 387 | |
| 388 | if (self.options.skip_non_native and !tests.isNative(&resolved_target, &b.graph.host.result)) continue; | |
| 388 | if (self.options.skip_non_native and !std.zig.target.isNative(&resolved_target.query, &resolved_target.result, &b.graph.host.result)) continue; | |
| 389 | 389 | |
| 390 | 390 | if (self.options.skip_freebsd and target.os.tag == .freebsd) continue; |
| 391 | 391 | if (self.options.skip_netbsd and target.os.tag == .netbsd) continue; |
test/src/StackTrace.zig+1-1| ... | ... | @@ -995,7 +995,7 @@ pub fn addCases(self: *StackTrace) void { |
| 995 | 995 | |
| 996 | 996 | if (!self.options.test_extra_targets and params.extra_target) continue; |
| 997 | 997 | |
| 998 | if (self.options.skip_non_native and !tests.isNative(&resolved_target, &b.graph.host.result)) continue; | |
| 998 | if (self.options.skip_non_native and !std.zig.target.isNative(&resolved_target.query, &resolved_target.result, &b.graph.host.result)) continue; | |
| 999 | 999 | |
| 1000 | 1000 | if (self.options.skip_freebsd and target.os.tag == .freebsd) continue; |
| 1001 | 1001 | if (self.options.skip_netbsd and target.os.tag == .netbsd) continue; |
test/tests.zig+4-160| ... | ... | @@ -2323,162 +2323,6 @@ pub const debugger_matrix: []const RunnerTarget = &.{ |
| 2323 | 2323 | }, |
| 2324 | 2324 | }; |
| 2325 | 2325 | |
| 2326 | fn supportedCompatArch(host: *const std.Target, arch: std.Target.Cpu.Arch) bool { | |
| 2327 | // aarch64-freebsd and aarch64-linux can technically run 32-bit ARM binaries, but that depends | |
| 2328 | // on AArch32 support in the CPU. Since modern AArch64 CPUs have largely dropped this support, | |
| 2329 | // avoid reporting compatibility for 32-bit here since we'd just build a bunch of test binaries | |
| 2330 | // that never get run anyway. This added almost an hour's worth of useless work to aarch64-linux | |
| 2331 | // CI, for example. | |
| 2332 | // | |
| 2333 | // riscv64-linux and riscv64-netbsd similarly support 32-bit binaries. However, this requires a | |
| 2334 | // very recent kernel and for the kernel feature to be enabled. Additionally, contemporary | |
| 2335 | // RISC-V hardware is just too slow to justify building the 32-bit binaries. | |
| 2336 | return switch (host.os.tag) { | |
| 2337 | .illumos => switch (host.cpu.arch) { | |
| 2338 | .x86_64 => arch == .x86, | |
| 2339 | else => false, | |
| 2340 | }, | |
| 2341 | .linux => switch (host.cpu.arch) { | |
| 2342 | .mips64 => arch == .mips, | |
| 2343 | .mips64el => arch == .mipsel, | |
| 2344 | .powerpc64 => arch == .powerpc, | |
| 2345 | .sparc64 => arch == .sparc, | |
| 2346 | .x86_64 => arch == .x86, | |
| 2347 | else => false, | |
| 2348 | }, | |
| 2349 | .netbsd => switch (host.cpu.arch) { | |
| 2350 | .sparc64 => arch == .sparc, | |
| 2351 | .x86_64 => arch == .x86, | |
| 2352 | else => false, | |
| 2353 | }, | |
| 2354 | .windows => switch (host.cpu.arch) { | |
| 2355 | .x86_64 => arch == .x86, | |
| 2356 | else => false, | |
| 2357 | }, | |
| 2358 | else => false, | |
| 2359 | }; | |
| 2360 | } | |
| 2361 | ||
| 2362 | pub fn isNative(actual_target: *const std.Build.ResolvedTarget, host: *const std.Target) bool { | |
| 2363 | if (actual_target.query.isNative()) return true; | |
| 2364 | const actual = &actual_target.result; | |
| 2365 | ||
| 2366 | if (actual.cpu.arch != host.cpu.arch and !supportedCompatArch(host, actual.cpu.arch)) | |
| 2367 | return false; | |
| 2368 | ||
| 2369 | if (actual.os.tag != host.os.tag) | |
| 2370 | return false; | |
| 2371 | ||
| 2372 | // This check is really only necessary for the case where `host.cpu.arch.isAarch64()` and | |
| 2373 | // `actual.cpu.arch.isArm()`. As they are wholly separate `std.Target` families with their own | |
| 2374 | // feature bits, the logic below would produce complete nonsense. | |
| 2375 | // | |
| 2376 | // This does mean that we aren't actually checking feature compatibility between these two | |
| 2377 | // families even though we should. That's not a problem currently, but in the future, we may | |
| 2378 | // need to add a special code path just for this specific case... | |
| 2379 | if (actual.cpu.arch.family() != host.cpu.arch.family()) | |
| 2380 | return true; | |
| 2381 | ||
| 2382 | // Remove features that don't actually affect compatibility. | |
| 2383 | const irrelevant: std.Target.Cpu.Feature.Set = switch (host.cpu.arch) { | |
| 2384 | .x86_64 => std.Target.x86.featureSet(&.{ | |
| 2385 | .@"16bit_mode", | |
| 2386 | .@"32bit_mode", | |
| 2387 | .@"64bit", | |
| 2388 | .false_deps_bls, | |
| 2389 | .false_deps_compress, | |
| 2390 | .false_deps_expand, | |
| 2391 | .false_deps_getmant, | |
| 2392 | .false_deps_lzcnt, | |
| 2393 | .false_deps_mulc, | |
| 2394 | .false_deps_mullq, | |
| 2395 | .false_deps_perm, | |
| 2396 | .false_deps_popcnt, | |
| 2397 | .false_deps_range, | |
| 2398 | .false_deps_tzcnt, | |
| 2399 | .fast_11bytenop, | |
| 2400 | .fast_15bytenop, | |
| 2401 | .fast_7bytenop, | |
| 2402 | .fast_bextr, | |
| 2403 | .fast_dpwssd, | |
| 2404 | .fast_gather, | |
| 2405 | .fast_hops, | |
| 2406 | .fast_imm16, | |
| 2407 | .fast_lzcnt, | |
| 2408 | .fast_movbe, | |
| 2409 | .fast_scalar_fsqrt, | |
| 2410 | .fast_scalar_shift_masks, | |
| 2411 | .fast_shld_rotate, | |
| 2412 | .fast_variable_crosslane_shuffle, | |
| 2413 | .fast_variable_perlane_shuffle, | |
| 2414 | .fast_vector_fsqrt, | |
| 2415 | .fast_vector_shift_masks, | |
| 2416 | .faster_shift_than_shuffle, | |
| 2417 | .no_bypass_delay, | |
| 2418 | .no_bypass_delay_blend, | |
| 2419 | .no_bypass_delay_mov, | |
| 2420 | .no_bypass_delay_shuffle, | |
| 2421 | .prefer_128_bit, | |
| 2422 | .prefer_256_bit, | |
| 2423 | .prefer_legacy_setcc, | |
| 2424 | .prefer_mask_registers, | |
| 2425 | .prefer_movmsk_over_vtest, | |
| 2426 | .prefer_ndd_mem, | |
| 2427 | .prefer_no_gather, | |
| 2428 | .prefer_no_scatter, | |
| 2429 | .slow_3ops_lea, | |
| 2430 | .slow_incdec, | |
| 2431 | .slow_indirect_call, | |
| 2432 | .slow_lea, | |
| 2433 | .slow_pmaddwd, | |
| 2434 | .slow_pmulld, | |
| 2435 | .slow_pmullq, | |
| 2436 | .slow_shld, | |
| 2437 | .slow_two_mem_ops, | |
| 2438 | .slow_unaligned_mem_16, | |
| 2439 | .slow_unaligned_mem_32, | |
| 2440 | }), | |
| 2441 | .aarch64, .aarch64_be => std.Target.aarch64.featureSet(&.{ | |
| 2442 | .addr_lsl_slow_14, | |
| 2443 | .align_cmp_csel_pairs, | |
| 2444 | .alu_lsl_fast, | |
| 2445 | .avoid_ldapur, | |
| 2446 | .disable_fast_inc_vl, | |
| 2447 | .exynos_cheap_as_move, | |
| 2448 | .fast_ld1_single, | |
| 2449 | .fixed_load_latency_4, | |
| 2450 | .fuse_address, | |
| 2451 | .fuse_addsub_2reg_const1, | |
| 2452 | .fuse_adrp_add, | |
| 2453 | .fuse_aes, | |
| 2454 | .fuse_arith_logic, | |
| 2455 | .fuse_crypto_eor, | |
| 2456 | .fuse_csel, | |
| 2457 | .fuse_cset, | |
| 2458 | .fuse_fcsel, | |
| 2459 | .fuse_literals, | |
| 2460 | .has_limited_64bit_vector_mul_bandwidth, | |
| 2461 | .predictable_select_expensive, | |
| 2462 | .slow_misaligned_128store, | |
| 2463 | .slow_paired_128, | |
| 2464 | .slow_strqro_store, | |
| 2465 | .use_experimental_zeroing_pseudos, | |
| 2466 | .use_fixed_over_scalable_if_equal_cost, | |
| 2467 | .use_postra_scheduler, | |
| 2468 | .use_reciprocal_square_root, | |
| 2469 | .use_wzr_to_vec_move, | |
| 2470 | }), | |
| 2471 | else => .empty, | |
| 2472 | }; | |
| 2473 | var set = actual.cpu.features; | |
| 2474 | set.removeFeatureSet(irrelevant); | |
| 2475 | ||
| 2476 | if (!host.cpu.features.isSuperSetOf(set)) | |
| 2477 | return false; | |
| 2478 | ||
| 2479 | return true; | |
| 2480 | } | |
| 2481 | ||
| 2482 | 2326 | pub fn addStackTraceTests(b: *std.Build, options: StackTracesContext.Options) *Step { |
| 2483 | 2327 | const step = b.step("test-stack-traces", "Run the stack trace tests"); |
| 2484 | 2328 | |
| ... | ... | @@ -2830,7 +2674,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 2830 | 2674 | |
| 2831 | 2675 | if (!options.test_extra_targets and test_target.extra_target) continue; |
| 2832 | 2676 | |
| 2833 | if (options.skip_non_native and !isNative(&resolved_target, &b.graph.host.result)) | |
| 2677 | if (options.skip_non_native and !std.zig.target.isNative(&resolved_target.query, &resolved_target.result, &b.graph.host.result)) | |
| 2834 | 2678 | continue; |
| 2835 | 2679 | |
| 2836 | 2680 | const target = &resolved_target.result; |
| ... | ... | @@ -3156,7 +3000,7 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step { |
| 3156 | 3000 | const triple_txt = resolved_target.query.zigTriple(b.allocator) catch @panic("OOM"); |
| 3157 | 3001 | const target = &resolved_target.result; |
| 3158 | 3002 | |
| 3159 | if (options.skip_non_native and !isNative(&resolved_target, &b.graph.host.result)) | |
| 3003 | if (options.skip_non_native and !std.zig.target.isNative(&resolved_target.query, &resolved_target.result, &b.graph.host.result)) | |
| 3160 | 3004 | continue; |
| 3161 | 3005 | |
| 3162 | 3006 | if (options.test_target_filters.len > 0) { |
| ... | ... | @@ -3249,7 +3093,7 @@ pub fn addLinkTests(b: *std.Build, options: LinkTestOptions) *Step { |
| 3249 | 3093 | for (link_targets) |link_target| { |
| 3250 | 3094 | const resolved_target = b.resolveTargetQuery(link_target.target); |
| 3251 | 3095 | |
| 3252 | if (options.skip_non_native and !isNative(&resolved_target, &b.graph.host.result)) | |
| 3096 | if (options.skip_non_native and !std.zig.target.isNative(&resolved_target.query, &resolved_target.result, &b.graph.host.result)) | |
| 3253 | 3097 | continue; |
| 3254 | 3098 | |
| 3255 | 3099 | const target = &resolved_target.result; |
| ... | ... | @@ -3399,7 +3243,7 @@ pub fn addRunnerTests( |
| 3399 | 3243 | for (matrix) |test_target| { |
| 3400 | 3244 | const resolved_target = b.resolveTargetQuery(test_target.target); |
| 3401 | 3245 | |
| 3402 | if (options.skip_non_native and !isNative(&resolved_target, &b.graph.host.result)) | |
| 3246 | if (options.skip_non_native and !std.zig.target.isNative(&resolved_target.query, &resolved_target.result, &b.graph.host.result)) | |
| 3403 | 3247 | continue; |
| 3404 | 3248 | |
| 3405 | 3249 | const target = &resolved_target.result; |