╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Air.zig ──────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
2502 pub fn unwrapShuffleTwo(air: *const Air, zcu: *const Zcu, inst_index: Inst.Index) UnwrappedShuffleTwo { 2503 const inst = air.instructions.get(@backingInt(inst_index)); 2504 switch (inst.tag) { 2505 .shuffle_two => {}, 2506 else => unreachable, // assertion failure 2507 } 2508 const result_ty: Type = inst.data.ty_pl.ty; 2509 const mask_len: u32 = result_ty.vectorLen(zcu); 2510 const extra_idx = inst.data.ty_pl.payload; 2511 return .{ 2512 .result_ty = result_ty, 2513 .operand_a = @fromBackingInt(@intCast(air.extra.items[extra_idx + mask_len + 0])), 2514 .operand_b = @fromBackingInt(@intCast(air.extra.items[extra_idx + mask_len + 1])), 2515 .mask = @ptrCast(air.extra.items[extra_idx..][0..mask_len]), 2516 }; 2517 } 2518 2519 pub const legalize = Legalize.legalize; 2520 pub const write = print.write; 2521 pub const writeInst = print.writeInst; 2522 pub const dump = print.dump; 2523 pub const dumpInst = print.dumpInst; 2524 2525 pub const CoveragePoint = enum(u1) { 2526 /// Indicates the block is not a place of interest corresponding to 2527 /// a source location for coverage purposes. 2528 none, 2529 /// Point of interest. The next instruction emitted corresponds to 2530 /// a source location used for coverage instrumentation. 2531 poi, 2532 }; 2533 2534 pub const CompilerRtFunc = enum(u32) { 2535 // zig fmt: off 2536 2537 // float simple arithmetic 2538 __addhf3, __addsf3, __adddf3, __addxf3, __addtf3, 2539 __subhf3, __subsf3, __subdf3, __subxf3, __subtf3, 2540 __mulhf3, __mulsf3, __muldf3, __mulxf3, __multf3, 2541 __divhf3, __divsf3, __divdf3, __divxf3, __divtf3, 2542 2543 // float minmax 2544 __fminh, fminf, fmin, __fminx, fminq, 2545 __fmaxh, fmaxf, fmax, __fmaxx, fmaxq, 2546 2547 // float round 2548 __ceilh, ceilf, ceil, __ceilx, ceilq, 2549 __floorh, floorf, floor, __floorx, floorq, 2550 __trunch, truncf, trunc, __truncx, truncq, 2551 __roundh, roundf, round, __roundx, roundq, 2552 2553 // float log 2554 __logh, logf, log, __logx, logq, 2555 __log2h, log2f, log2, __log2x, log2q, 2556 __log10h, log10f, log10, __log10x, log10q, 2557 2558 // float exp 2559 __exph, expf, exp, __expx, expq, 2560 __exp2h, exp2f, exp2, __exp2x, exp2q, 2561 2562 // float trigonometry 2563 __sinh, sinf, sin, __sinx, sinq, 2564 __cosh, cosf, cos, __cosx, cosq, 2565 __tanh, tanf, tan, __tanx, tanq, 2566 2567 // float misc ops 2568 __fabsh, fabsf, fabs, __fabsx, fabsq, 2569 __sqrth, sqrtf, sqrt, __sqrtx, sqrtq, 2570 __fmodh, fmodf, fmod, __fmodx, fmodq, 2571 __fmah, fmaf, fma, __fmax, fmaq, 2572 2573 // float comparison 2574 __eqhf2, __eqsf2, __eqdf2, __eqxf2, __eqtf2, // == iff return == 0 2575 __nehf2, __nesf2, __nedf2, __nexf2, __netf2, // != iff return != 0 2576 __lthf2, __ltsf2, __ltdf2, __ltxf2, __lttf2, // < iff return < 0 2577 __lehf2, __lesf2, __ledf2, __lexf2, __letf2, // <= iff return <= 0 2578 __gthf2, __gtsf2, __gtdf2, __gtxf2, __gttf2, // > iff return > 0 2579 __gehf2, __gesf2, __gedf2, __gexf2, __getf2, // >= iff return >= 0 2580 2581 // AEABI float comparison. On ARM, the `sf`/`df` functions above are not available, 2582 // and these must be used instead. They are not just aliases for the above functions 2583 // because they have a different (better) ABI. 2584 __aeabi_fcmpeq, __aeabi_dcmpeq, // ==, returns bool 2585 __aeabi_fcmplt, __aeabi_dcmplt, // <, returns bool 2586 __aeabi_fcmple, __aeabi_dcmple, // <=, returns bool 2587 __aeabi_fcmpgt, __aeabi_dcmpgt, // >, returns bool 2588 __aeabi_fcmpge, __aeabi_dcmpge, // >=, returns bool 2589 2590 // float shortening 2591 // to f16 // to f32 // to f64 // to f80 2592 __trunctfhf2, __trunctfsf2, __trunctfdf2, __trunctfxf2, // from f128 2593 __truncxfhf2, __truncxfsf2, __truncxfdf2, // from f80 2594 __truncdfhf2, __truncdfsf2, // from f64 2595 __truncsfhf2, // from f32 2596 2597 // float widening 2598 // to f128 // to f80 // to f64 // to f32 2599 __extendhftf2, __extendhfxf2, __extendhfdf2, __extendhfsf2, // from f16 2600 __extendsftf2, __extendsfxf2, __extendsfdf2, // from f32 2601 __extenddftf2, __extenddfxf2, // from f64 2602 __extendxftf2, // from f80 2603 2604 // int to float 2605 __floatsihf, __floatsisf, __floatsidf, __floatsixf, __floatsitf, // i32 to float 2606 __floatdihf, __floatdisf, __floatdidf, __floatdixf, __floatditf, // i64 to float 2607 __floattihf, __floattisf, __floattidf, __floattixf, __floattitf, // i128 to float 2608 __floateihf, __floateisf, __floateidf, __floateixf, __floateitf, // arbitrary iN to float 2609 __floatunsihf, __floatunsisf, __floatunsidf, __floatunsixf, __floatunsitf, // u32 to float 2610 __floatundihf, __floatundisf, __floatundidf, __floatundixf, __floatunditf, // u64 to float 2611 __floatuntihf, __floatuntisf, __floatuntidf, __floatuntixf, __floatuntitf, // u128 to float 2612 __floatuneihf, __floatuneisf, __floatuneidf, __floatuneixf, __floatuneitf, // arbitrary uN to float 2613 2614 // float to int 2615 __fixhfsi, __fixsfsi, __fixdfsi, __fixxfsi, __fixtfsi, // float to i32 2616 __fixhfdi, __fixsfdi, __fixdfdi, __fixxfdi, __fixtfdi, // float to i64 2617 __fixhfti, __fixsfti, __fixdfti, __fixxfti, __fixtfti, // float to i128 2618 __fixhfei, __fixsfei, __fixdfei, __fixxfei, __fixtfei, // float to arbitray iN 2619 __fixunshfsi, __fixunssfsi, __fixunsdfsi, __fixunsxfsi, __fixunstfsi, // float to u32 2620 __fixunshfdi, __fixunssfdi, __fixunsdfdi, __fixunsxfdi, __fixunstfdi, // float to u64 2621 __fixunshfti, __fixunssfti, __fixunsdfti, __fixunsxfti, __fixunstfti, // float to u128 2622 __fixunshfei, __fixunssfei, __fixunsdfei, __fixunsxfei, __fixunstfei, // float to arbitray uN 2623 2624 // zig fmt: on 2625 2626 /// Usually, the tag names of `CompilerRtFunc` match the corresponding symbol name, but not 2627 /// always; some target triples have slightly different compiler-rt ABIs for one reason or 2628 /// another. 2629 pub fn name(f: CompilerRtFunc, target: *const std.Target) []const u8 { 2630 const use_gnu_f16_abi = switch (target.cpu.arch) { 2631 .wasm32, 2632 .wasm64, 2633 .riscv64, 2634 .riscv64be, 2635 .riscv32, 2636 .riscv32be, 2637 => false, 2638 .x86, .x86_64 => true, 2639 .arm, .armeb, .thumb, .thumbeb => switch (target.abi) { 2640 .eabi, .eabihf => false, 2641 else => true, 2642 }, 2643 else => !target.os.tag.isDarwin(), 2644 }; 2645 const use_aeabi = target.cpu.arch.isArm() and switch (target.abi) { 2646 .eabi, 2647 .eabihf, 2648 .musleabi, 2649 .musleabihf, 2650 .gnueabi, 2651 .gnueabihf, 2652 .android, 2653 .androideabi, 2654 => true, 2655 else => false, 2656 }; 2657 2658 // GNU didn't like the standard names specifically for conversions between f16 2659 // and f32, so decided to make their own naming convention with blackjack and 2660 // hookers (but only use it on a few random targets of course). This overrides 2661 // the ARM EABI in some cases. I don't like GNU. 2662 if (use_gnu_f16_abi) switch (f) { 2663 .__truncsfhf2 => return "__gnu_f2h_ieee", 2664 .__extendhfsf2 => return "__gnu_h2f_ieee", 2665 else => {}, 2666 }; 2667 2668 if (use_aeabi) return switch (f) { 2669 .__addsf3 => "__aeabi_fadd", 2670 .__adddf3 => "__aeabi_dadd", 2671 .__subsf3 => "__aeabi_fsub", 2672 .__subdf3 => "__aeabi_dsub", 2673 .__mulsf3 => "__aeabi_fmul", 2674 .__muldf3 => "__aeabi_dmul", 2675 .__divsf3 => "__aeabi_fdiv", 2676 .__divdf3 => "__aeabi_ddiv", 2677 .__truncdfhf2 => "__aeabi_d2h", 2678 .__truncdfsf2 => "__aeabi_d2f", 2679 .__truncsfhf2 => "__aeabi_f2h", 2680 .__extendsfdf2 => "__aeabi_f2d", 2681 .__extendhfsf2 => "__aeabi_h2f", 2682 .__floatsisf => "__aeabi_i2f", 2683 .__floatsidf => "__aeabi_i2d", 2684 .__floatdisf => "__aeabi_l2f", 2685 .__floatdidf => "__aeabi_l2d", 2686 .__floatunsisf => "__aeabi_ui2f", 2687 .__floatunsidf => "__aeabi_ui2d", 2688 .__floatundisf => "__aeabi_ul2f", 2689 .__floatundidf => "__aeabi_ul2d", 2690 .__fixsfsi => "__aeabi_f2iz", 2691 .__fixdfsi => "__aeabi_d2iz", 2692 .__fixsfdi => "__aeabi_f2lz", 2693 .__fixdfdi => "__aeabi_d2lz", 2694 .__fixunssfsi => "__aeabi_f2uiz", 2695 .__fixunsdfsi => "__aeabi_d2uiz", 2696 .__fixunssfdi => "__aeabi_f2ulz", 2697 .__fixunsdfdi => "__aeabi_d2ulz", 2698 2699 // These functions are not available on AEABI. The AEABI equivalents are 2700 // separate fields rather than aliases because they have a different ABI. 2701 .__eqsf2, .__eqdf2 => unreachable, 2702 .__nesf2, .__nedf2 => unreachable, 2703 .__ltsf2, .__ltdf2 => unreachable, 2704 .__lesf2, .__ledf2 => unreachable, 2705 .__gtsf2, .__gtdf2 => unreachable, 2706 .__gesf2, .__gedf2 => unreachable, 2707 2708 else => @tagName(f), 2709 }; 2710 2711 return switch (f) { 2712 // These functions are only available on AEABI. 2713 .__aeabi_fcmpeq, .__aeabi_dcmpeq => unreachable, 2714 .__aeabi_fcmplt, .__aeabi_dcmplt => unreachable, 2715 .__aeabi_fcmple, .__aeabi_dcmple => unreachable, 2716 .__aeabi_fcmpgt, .__aeabi_dcmpgt => unreachable, 2717 .__aeabi_fcmpge, .__aeabi_dcmpge => unreachable, 2718 2719 else => @tagName(f), 2720 }; 2721 } 2722 2723 pub fn @"callconv"(f: CompilerRtFunc, target: *const std.Target) std.lang.CallingConvention { 2724 const use_gnu_f16_abi = switch (target.cpu.arch) { 2725 .wasm32, 2726 .wasm64, 2727 .riscv64, 2728 .riscv64be, 2729 .riscv32, 2730 .riscv32be, 2731 => false, 2732 .x86, .x86_64 => true, 2733 .arm, .armeb, .thumb, .thumbeb => switch (target.abi) { 2734 .eabi, .eabihf => false, 2735 else => true, 2736 }, 2737 else => !target.os.tag.isDarwin(), 2738 }; 2739 const use_aeabi = target.cpu.arch.isArm() and switch (target.abi) { 2740 .eabi, 2741 .eabihf, 2742 .musleabi, 2743 .musleabihf, 2744 .gnueabi, 2745 .gnueabihf, 2746 .android, 2747 .androideabi, 2748 => true, 2749 else => false, 2750 }; 2751 2752 if (use_gnu_f16_abi) switch (f) { 2753 .__truncsfhf2, 2754 .__extendhfsf2, 2755 => return target.cCallingConvention().?, 2756 else => {}, 2757 }; 2758 2759 if (use_aeabi) switch (f) { 2760 // zig fmt: off 2761 .__addsf3, .__adddf3, .__subsf3, .__subdf3, 2762 .__mulsf3, .__muldf3, .__divsf3, .__divdf3, 2763 .__truncdfhf2, .__truncdfsf2, .__truncsfhf2, 2764 .__extendsfdf2, .__extendhfsf2, 2765 .__floatsisf, .__floatsidf, .__floatdisf, .__floatdidf, 2766 .__floatunsisf, .__floatunsidf, .__floatundisf, .__floatundidf, 2767 .__fixsfsi, .__fixdfsi, .__fixsfdi, .__fixdfdi, 2768 .__fixunssfsi, .__fixunsdfsi, .__fixunssfdi, .__fixunsdfdi, 2769 => return .{ .arm_aapcs = .{} }, 2770 // zig fmt: on 2771 else => {}, 2772 }; 2773 2774 return target.cCallingConvention().?; 2775 } 2776 2777 pub fn returnType(f: CompilerRtFunc) Type { 2778 return switch (f) { 2779 .__addhf3, .__subhf3, .__mulhf3, .__divhf3 => .f16, 2780 .__addsf3, .__subsf3, .__mulsf3, .__divsf3 => .f32, 2781 .__adddf3, .__subdf3, .__muldf3, .__divdf3 => .f64, 2782 .__addxf3, .__subxf3, .__mulxf3, .__divxf3 => .f80, 2783 .__addtf3, .__subtf3, .__multf3, .__divtf3 => .f128, 2784 2785 // zig fmt: off 2786 .__fminh, .__fmaxh, 2787 .__ceilh, .__floorh, .__trunch, .__roundh, 2788 .__logh, .__log2h, .__log10h, 2789 .__exph, .__exp2h, 2790 .__sinh, .__cosh, .__tanh, 2791 .__fabsh, .__sqrth, .__fmodh, .__fmah, 2792 => .f16, 2793 .fminf, .fmaxf, 2794 .ceilf, .floorf, .truncf, .roundf, 2795 .logf, .log2f, .log10f, 2796 .expf, .exp2f, 2797 .sinf, .cosf, .tanf, 2798 .fabsf, .sqrtf, .fmodf, .fmaf, 2799 => .f32, 2800 .fmin, .fmax, 2801 .ceil, .floor, .trunc, .round, 2802 .log, .log2, .log10, 2803 .exp, .exp2, 2804 .sin, .cos, .tan, 2805 .fabs, .sqrt, .fmod, .fma, 2806 => .f64, 2807 .__fminx, .__fmaxx, 2808 .__ceilx, .__floorx, .__truncx, .__roundx, 2809 .__logx, .__log2x, .__log10x, 2810 .__expx, .__exp2x, 2811 .__sinx, .__cosx, .__tanx, 2812 .__fabsx, .__sqrtx, .__fmodx, .__fmax, 2813 => .f80, 2814 .fminq, .fmaxq, 2815 .ceilq, .floorq, .truncq, .roundq, 2816 .logq, .log2q, .log10q, 2817 .expq, .exp2q, 2818 .sinq, .cosq, .tanq, 2819 .fabsq, .sqrtq, .fmodq, .fmaq, 2820 => .f128, 2821 // zig fmt: on 2822 2823 .__eqhf2, .__eqsf2, .__eqdf2, .__eqxf2, .__eqtf2 => .i32, 2824 .__nehf2, .__nesf2, .__nedf2, .__nexf2, .__netf2 => .i32, 2825 .__lthf2, .__ltsf2, .__ltdf2, .__ltxf2, .__lttf2 => .i32, 2826 .__lehf2, .__lesf2, .__ledf2, .__lexf2, .__letf2 => .i32, 2827 .__gthf2, .__gtsf2, .__gtdf2, .__gtxf2, .__gttf2 => .i32, 2828 .__gehf2, .__gesf2, .__gedf2, .__gexf2, .__getf2 => .i32, 2829 2830 .__aeabi_fcmpeq, .__aeabi_dcmpeq => .i32, 2831 .__aeabi_fcmplt, .__aeabi_dcmplt => .i32, 2832 .__aeabi_fcmple, .__aeabi_dcmple => .i32, 2833 .__aeabi_fcmpgt, .__aeabi_dcmpgt => .i32, 2834 .__aeabi_fcmpge, .__aeabi_dcmpge => .i32, 2835 2836 .__trunctfhf2, .__truncxfhf2, .__truncdfhf2, .__truncsfhf2 => .f16, 2837 .__trunctfsf2, .__truncxfsf2, .__truncdfsf2 => .f32, 2838 .__trunctfdf2, .__truncxfdf2 => .f64, 2839 .__trunctfxf2 => .f80, 2840 2841 .__extendhftf2, .__extendsftf2, .__extenddftf2, .__extendxftf2 => .f128, 2842 .__extendhfxf2, .__extendsfxf2, .__extenddfxf2 => .f80, 2843 .__extendhfdf2, .__extendsfdf2 => .f64, 2844 .__extendhfsf2 => .f32, 2845 2846 .__floatsihf, .__floatdihf, .__floattihf, .__floateihf => .f16, 2847 .__floatsisf, .__floatdisf, .__floattisf, .__floateisf => .f32, 2848 .__floatsidf, .__floatdidf, .__floattidf, .__floateidf => .f64, 2849 .__floatsixf, .__floatdixf, .__floattixf, .__floateixf => .f80, 2850 .__floatsitf, .__floatditf, .__floattitf, .__floateitf => .f128, 2851 .__floatunsihf, .__floatundihf, .__floatuntihf, .__floatuneihf => .f16, 2852 .__floatunsisf, .__floatundisf, .__floatuntisf, .__floatuneisf => .f32, 2853 .__floatunsidf, .__floatundidf, .__floatuntidf, .__floatuneidf => .f64, 2854 .__floatunsixf, .__floatundixf, .__floatuntixf, .__floatuneixf => .f80, 2855 .__floatunsitf, .__floatunditf, .__floatuntitf, .__floatuneitf => .f128, 2856 2857 .__fixhfsi, .__fixsfsi, .__fixdfsi, .__fixxfsi, .__fixtfsi => .i32, 2858 .__fixhfdi, .__fixsfdi, .__fixdfdi, .__fixxfdi, .__fixtfdi => .i64, 2859 .__fixhfti, .__fixsfti, .__fixdfti, .__fixxfti, .__fixtfti => .i128, 2860 .__fixhfei, .__fixsfei, .__fixdfei, .__fixxfei, .__fixtfei => .void, 2861 .__fixunshfsi, .__fixunssfsi, .__fixunsdfsi, .__fixunsxfsi, .__fixunstfsi => .u32, 2862 .__fixunshfdi, .__fixunssfdi, .__fixunsdfdi, .__fixunsxfdi, .__fixunstfdi => .u64, 2863 .__fixunshfti, .__fixunssfti, .__fixunsdfti, .__fixunsxfti, .__fixunstfti => .u128, 2864 .__fixunshfei, .__fixunssfei, .__fixunsdfei, .__fixunsxfei, .__fixunstfei => .void, 2865 }; 2866 } 2867 }; 2868