| author | |
| committer | |
| log | 7b01af2bfd4cf9232fb0157c26d7c59642452fab |
| tree | 733810a59ad5a4177198d60b9058e2951567a94a |
| parent | a63134a4a56e8683aeee292b641b4e943cbfb999 |
| parent | 1efd36cd5c9a1128ae702b081d60ee32f21bc258 |
| signature |
CBE: add support for integers larger than 128 bits (and apparently vectors too)21 files changed, 2445 insertions(+), 857 deletions(-)
lib/std/math/big/int.zig+1| ... | ... | @@ -1674,6 +1674,7 @@ pub const Mutable = struct { |
| 1674 | 1674 | |
| 1675 | 1675 | /// If a is positive, this passes through to truncate. |
| 1676 | 1676 | /// If a is negative, then r is set to positive with the bit pattern ~(a - 1). |
| 1677 | /// r may alias a. | |
| 1677 | 1678 | /// |
| 1678 | 1679 | /// Asserts `r` has enough storage to store the result. |
| 1679 | 1680 | /// The upper bound is `calcTwosCompLimbCount(a.len)`. |
lib/zig.h+1035-212| ... | ... | @@ -37,6 +37,14 @@ typedef char bool; |
| 37 | 37 | #define zig_has_attribute(attribute) 0 |
| 38 | 38 | #endif |
| 39 | 39 | |
| 40 | #if __LITTLE_ENDIAN__ || _MSC_VER | |
| 41 | #define zig_little_endian 1 | |
| 42 | #define zig_big_endian 0 | |
| 43 | #else | |
| 44 | #define zig_little_endian 0 | |
| 45 | #define zig_big_endian 1 | |
| 46 | #endif | |
| 47 | ||
| 40 | 48 | #if __STDC_VERSION__ >= 201112L |
| 41 | 49 | #define zig_threadlocal _Thread_local |
| 42 | 50 | #elif defined(__GNUC__) |
| ... | ... | @@ -604,12 +612,6 @@ static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 604 | 612 | #endif |
| 605 | 613 | } |
| 606 | 614 | |
| 607 | static inline void zig_vaddo_u32(uint8_t *ov, uint32_t *res, int n, | |
| 608 | const uint32_t *lhs, const uint32_t *rhs, uint8_t bits) | |
| 609 | { | |
| 610 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u32(&res[i], lhs[i], rhs[i], bits); | |
| 611 | } | |
| 612 | ||
| 613 | 615 | zig_extern int32_t __addosi4(int32_t lhs, int32_t rhs, int *overflow); |
| 614 | 616 | static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 615 | 617 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -624,12 +626,6 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 624 | 626 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 625 | 627 | } |
| 626 | 628 | |
| 627 | static inline void zig_vaddo_i32(uint8_t *ov, int32_t *res, int n, | |
| 628 | const int32_t *lhs, const int32_t *rhs, uint8_t bits) | |
| 629 | { | |
| 630 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i32(&res[i], lhs[i], rhs[i], bits); | |
| 631 | } | |
| 632 | ||
| 633 | 629 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 634 | 630 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 635 | 631 | uint64_t full_res; |
| ... | ... | @@ -642,12 +638,6 @@ static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 642 | 638 | #endif |
| 643 | 639 | } |
| 644 | 640 | |
| 645 | static inline void zig_vaddo_u64(uint8_t *ov, uint64_t *res, int n, | |
| 646 | const uint64_t *lhs, const uint64_t *rhs, uint8_t bits) | |
| 647 | { | |
| 648 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u64(&res[i], lhs[i], rhs[i], bits); | |
| 649 | } | |
| 650 | ||
| 651 | 641 | zig_extern int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow); |
| 652 | 642 | static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 653 | 643 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -662,12 +652,6 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 662 | 652 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 663 | 653 | } |
| 664 | 654 | |
| 665 | static inline void zig_vaddo_i64(uint8_t *ov, int64_t *res, int n, | |
| 666 | const int64_t *lhs, const int64_t *rhs, uint8_t bits) | |
| 667 | { | |
| 668 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i64(&res[i], lhs[i], rhs[i], bits); | |
| 669 | } | |
| 670 | ||
| 671 | 655 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 672 | 656 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 673 | 657 | uint8_t full_res; |
| ... | ... | @@ -682,12 +666,6 @@ static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 682 | 666 | #endif |
| 683 | 667 | } |
| 684 | 668 | |
| 685 | static inline void zig_vaddo_u8(uint8_t *ov, uint8_t *res, int n, | |
| 686 | const uint8_t *lhs, const uint8_t *rhs, uint8_t bits) | |
| 687 | { | |
| 688 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u8(&res[i], lhs[i], rhs[i], bits); | |
| 689 | } | |
| 690 | ||
| 691 | 669 | static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) { |
| 692 | 670 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 693 | 671 | int8_t full_res; |
| ... | ... | @@ -702,12 +680,6 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 702 | 680 | #endif |
| 703 | 681 | } |
| 704 | 682 | |
| 705 | static inline void zig_vaddo_i8(uint8_t *ov, int8_t *res, int n, | |
| 706 | const int8_t *lhs, const int8_t *rhs, uint8_t bits) | |
| 707 | { | |
| 708 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i8(&res[i], lhs[i], rhs[i], bits); | |
| 709 | } | |
| 710 | ||
| 711 | 683 | static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) { |
| 712 | 684 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 713 | 685 | uint16_t full_res; |
| ... | ... | @@ -722,12 +694,6 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 722 | 694 | #endif |
| 723 | 695 | } |
| 724 | 696 | |
| 725 | static inline void zig_vaddo_u16(uint8_t *ov, uint16_t *res, int n, | |
| 726 | const uint16_t *lhs, const uint16_t *rhs, uint8_t bits) | |
| 727 | { | |
| 728 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u16(&res[i], lhs[i], rhs[i], bits); | |
| 729 | } | |
| 730 | ||
| 731 | 697 | static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) { |
| 732 | 698 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 733 | 699 | int16_t full_res; |
| ... | ... | @@ -742,12 +708,6 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 742 | 708 | #endif |
| 743 | 709 | } |
| 744 | 710 | |
| 745 | static inline void zig_vaddo_i16(uint8_t *ov, int16_t *res, int n, | |
| 746 | const int16_t *lhs, const int16_t *rhs, uint8_t bits) | |
| 747 | { | |
| 748 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i16(&res[i], lhs[i], rhs[i], bits); | |
| 749 | } | |
| 750 | ||
| 751 | 711 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 752 | 712 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 753 | 713 | uint32_t full_res; |
| ... | ... | @@ -760,12 +720,6 @@ static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 760 | 720 | #endif |
| 761 | 721 | } |
| 762 | 722 | |
| 763 | static inline void zig_vsubo_u32(uint8_t *ov, uint32_t *res, int n, | |
| 764 | const uint32_t *lhs, const uint32_t *rhs, uint8_t bits) | |
| 765 | { | |
| 766 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u32(&res[i], lhs[i], rhs[i], bits); | |
| 767 | } | |
| 768 | ||
| 769 | 723 | zig_extern int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow); |
| 770 | 724 | static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 771 | 725 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -780,12 +734,6 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 780 | 734 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 781 | 735 | } |
| 782 | 736 | |
| 783 | static inline void zig_vsubo_i32(uint8_t *ov, int32_t *res, int n, | |
| 784 | const int32_t *lhs, const int32_t *rhs, uint8_t bits) | |
| 785 | { | |
| 786 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i32(&res[i], lhs[i], rhs[i], bits); | |
| 787 | } | |
| 788 | ||
| 789 | 737 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 790 | 738 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 791 | 739 | uint64_t full_res; |
| ... | ... | @@ -798,12 +746,6 @@ static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 798 | 746 | #endif |
| 799 | 747 | } |
| 800 | 748 | |
| 801 | static inline void zig_vsubo_u64(uint8_t *ov, uint64_t *res, int n, | |
| 802 | const uint64_t *lhs, const uint64_t *rhs, uint8_t bits) | |
| 803 | { | |
| 804 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u64(&res[i], lhs[i], rhs[i], bits); | |
| 805 | } | |
| 806 | ||
| 807 | 749 | zig_extern int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow); |
| 808 | 750 | static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 809 | 751 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -818,12 +760,6 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 818 | 760 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 819 | 761 | } |
| 820 | 762 | |
| 821 | static inline void zig_vsubo_i64(uint8_t *ov, int64_t *res, int n, | |
| 822 | const int64_t *lhs, const int64_t *rhs, uint8_t bits) | |
| 823 | { | |
| 824 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i64(&res[i], lhs[i], rhs[i], bits); | |
| 825 | } | |
| 826 | ||
| 827 | 763 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 828 | 764 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 829 | 765 | uint8_t full_res; |
| ... | ... | @@ -838,12 +774,6 @@ static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 838 | 774 | #endif |
| 839 | 775 | } |
| 840 | 776 | |
| 841 | static inline void zig_vsubo_u8(uint8_t *ov, uint8_t *res, int n, | |
| 842 | const uint8_t *lhs, const uint8_t *rhs, uint8_t bits) | |
| 843 | { | |
| 844 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u8(&res[i], lhs[i], rhs[i], bits); | |
| 845 | } | |
| 846 | ||
| 847 | 777 | static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) { |
| 848 | 778 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 849 | 779 | int8_t full_res; |
| ... | ... | @@ -858,13 +788,6 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 858 | 788 | #endif |
| 859 | 789 | } |
| 860 | 790 | |
| 861 | static inline void zig_vsubo_i8(uint8_t *ov, int8_t *res, int n, | |
| 862 | const int8_t *lhs, const int8_t *rhs, uint8_t bits) | |
| 863 | { | |
| 864 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i8(&res[i], lhs[i], rhs[i], bits); | |
| 865 | } | |
| 866 | ||
| 867 | ||
| 868 | 791 | static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) { |
| 869 | 792 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 870 | 793 | uint16_t full_res; |
| ... | ... | @@ -879,13 +802,6 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 879 | 802 | #endif |
| 880 | 803 | } |
| 881 | 804 | |
| 882 | static inline void zig_vsubo_u16(uint8_t *ov, uint16_t *res, int n, | |
| 883 | const uint16_t *lhs, const uint16_t *rhs, uint8_t bits) | |
| 884 | { | |
| 885 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u16(&res[i], lhs[i], rhs[i], bits); | |
| 886 | } | |
| 887 | ||
| 888 | ||
| 889 | 805 | static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) { |
| 890 | 806 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 891 | 807 | int16_t full_res; |
| ... | ... | @@ -900,12 +816,6 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 900 | 816 | #endif |
| 901 | 817 | } |
| 902 | 818 | |
| 903 | static inline void zig_vsubo_i16(uint8_t *ov, int16_t *res, int n, | |
| 904 | const int16_t *lhs, const int16_t *rhs, uint8_t bits) | |
| 905 | { | |
| 906 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i16(&res[i], lhs[i], rhs[i], bits); | |
| 907 | } | |
| 908 | ||
| 909 | 819 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 910 | 820 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 911 | 821 | uint32_t full_res; |
| ... | ... | @@ -918,12 +828,6 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 918 | 828 | #endif |
| 919 | 829 | } |
| 920 | 830 | |
| 921 | static inline void zig_vmulo_u32(uint8_t *ov, uint32_t *res, int n, | |
| 922 | const uint32_t *lhs, const uint32_t *rhs, uint8_t bits) | |
| 923 | { | |
| 924 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u32(&res[i], lhs[i], rhs[i], bits); | |
| 925 | } | |
| 926 | ||
| 927 | 831 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); |
| 928 | 832 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 929 | 833 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -938,12 +842,6 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 938 | 842 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 939 | 843 | } |
| 940 | 844 | |
| 941 | static inline void zig_vmulo_i32(uint8_t *ov, int32_t *res, int n, | |
| 942 | const int32_t *lhs, const int32_t *rhs, uint8_t bits) | |
| 943 | { | |
| 944 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i32(&res[i], lhs[i], rhs[i], bits); | |
| 945 | } | |
| 946 | ||
| 947 | 845 | static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 948 | 846 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 949 | 847 | uint64_t full_res; |
| ... | ... | @@ -956,12 +854,6 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 956 | 854 | #endif |
| 957 | 855 | } |
| 958 | 856 | |
| 959 | static inline void zig_vmulo_u64(uint8_t *ov, uint64_t *res, int n, | |
| 960 | const uint64_t *lhs, const uint64_t *rhs, uint8_t bits) | |
| 961 | { | |
| 962 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u64(&res[i], lhs[i], rhs[i], bits); | |
| 963 | } | |
| 964 | ||
| 965 | 857 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); |
| 966 | 858 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 967 | 859 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -976,12 +868,6 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 976 | 868 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 977 | 869 | } |
| 978 | 870 | |
| 979 | static inline void zig_vmulo_i64(uint8_t *ov, int64_t *res, int n, | |
| 980 | const int64_t *lhs, const int64_t *rhs, uint8_t bits) | |
| 981 | { | |
| 982 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i64(&res[i], lhs[i], rhs[i], bits); | |
| 983 | } | |
| 984 | ||
| 985 | 871 | static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 986 | 872 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 987 | 873 | uint8_t full_res; |
| ... | ... | @@ -996,12 +882,6 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 996 | 882 | #endif |
| 997 | 883 | } |
| 998 | 884 | |
| 999 | static inline void zig_vmulo_u8(uint8_t *ov, uint8_t *res, int n, | |
| 1000 | const uint8_t *lhs, const uint8_t *rhs, uint8_t bits) | |
| 1001 | { | |
| 1002 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u8(&res[i], lhs[i], rhs[i], bits); | |
| 1003 | } | |
| 1004 | ||
| 1005 | 885 | static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) { |
| 1006 | 886 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 1007 | 887 | int8_t full_res; |
| ... | ... | @@ -1016,12 +896,6 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 1016 | 896 | #endif |
| 1017 | 897 | } |
| 1018 | 898 | |
| 1019 | static inline void zig_vmulo_i8(uint8_t *ov, int8_t *res, int n, | |
| 1020 | const int8_t *lhs, const int8_t *rhs, uint8_t bits) | |
| 1021 | { | |
| 1022 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i8(&res[i], lhs[i], rhs[i], bits); | |
| 1023 | } | |
| 1024 | ||
| 1025 | 899 | static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) { |
| 1026 | 900 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 1027 | 901 | uint16_t full_res; |
| ... | ... | @@ -1036,12 +910,6 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1036 | 910 | #endif |
| 1037 | 911 | } |
| 1038 | 912 | |
| 1039 | static inline void zig_vmulo_u16(uint8_t *ov, uint16_t *res, int n, | |
| 1040 | const uint16_t *lhs, const uint16_t *rhs, uint8_t bits) | |
| 1041 | { | |
| 1042 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u16(&res[i], lhs[i], rhs[i], bits); | |
| 1043 | } | |
| 1044 | ||
| 1045 | 913 | static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) { |
| 1046 | 914 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 1047 | 915 | int16_t full_res; |
| ... | ... | @@ -1056,12 +924,6 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1056 | 924 | #endif |
| 1057 | 925 | } |
| 1058 | 926 | |
| 1059 | static inline void zig_vmulo_i16(uint8_t *ov, int16_t *res, int n, | |
| 1060 | const int16_t *lhs, const int16_t *rhs, uint8_t bits) | |
| 1061 | { | |
| 1062 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i16(&res[i], lhs[i], rhs[i], bits); | |
| 1063 | } | |
| 1064 | ||
| 1065 | 927 | #define zig_int_builtins(w) \ |
| 1066 | 928 | static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 1067 | 929 | *res = zig_shlw_u##w(lhs, rhs, bits); \ |
| ... | ... | @@ -1360,8 +1222,8 @@ typedef signed __int128 zig_i128; |
| 1360 | 1222 | |
| 1361 | 1223 | #define zig_make_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) |
| 1362 | 1224 | #define zig_make_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo)) |
| 1363 | #define zig_make_constant_u128(hi, lo) zig_make_u128(hi, lo) | |
| 1364 | #define zig_make_constant_i128(hi, lo) zig_make_i128(hi, lo) | |
| 1225 | #define zig_init_u128(hi, lo) zig_make_u128(hi, lo) | |
| 1226 | #define zig_init_i128(hi, lo) zig_make_i128(hi, lo) | |
| 1365 | 1227 | #define zig_hi_u128(val) ((uint64_t)((val) >> 64)) |
| 1366 | 1228 | #define zig_lo_u128(val) ((uint64_t)((val) >> 0)) |
| 1367 | 1229 | #define zig_hi_i128(val) (( int64_t)((val) >> 64)) |
| ... | ... | @@ -1379,7 +1241,7 @@ typedef signed __int128 zig_i128; |
| 1379 | 1241 | |
| 1380 | 1242 | #else /* zig_has_int128 */ |
| 1381 | 1243 | |
| 1382 | #if __LITTLE_ENDIAN__ || _MSC_VER | |
| 1244 | #if zig_little_endian | |
| 1383 | 1245 | typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128; |
| 1384 | 1246 | typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128; |
| 1385 | 1247 | #else |
| ... | ... | @@ -1391,11 +1253,11 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128; |
| 1391 | 1253 | #define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) }) |
| 1392 | 1254 | |
| 1393 | 1255 | #if _MSC_VER /* MSVC doesn't allow struct literals in constant expressions */ |
| 1394 | #define zig_make_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1395 | #define zig_make_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1256 | #define zig_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1257 | #define zig_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1396 | 1258 | #else /* But non-MSVC doesn't like the unprotected commas */ |
| 1397 | #define zig_make_constant_u128(hi, lo) zig_make_u128(hi, lo) | |
| 1398 | #define zig_make_constant_i128(hi, lo) zig_make_i128(hi, lo) | |
| 1259 | #define zig_init_u128(hi, lo) zig_make_u128(hi, lo) | |
| 1260 | #define zig_init_i128(hi, lo) zig_make_i128(hi, lo) | |
| 1399 | 1261 | #endif |
| 1400 | 1262 | #define zig_hi_u128(val) ((val).hi) |
| 1401 | 1263 | #define zig_lo_u128(val) ((val).lo) |
| ... | ... | @@ -1638,7 +1500,9 @@ static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) { |
| 1638 | 1500 | } |
| 1639 | 1501 | |
| 1640 | 1502 | static inline zig_i128 zig_wrap_i128(zig_i128 val, uint8_t bits) { |
| 1641 | return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val)); | |
| 1503 | if (bits > UINT8_C(64)) return zig_make_i128(zig_wrap_i64(zig_hi_i128(val), bits - UINT8_C(64)), zig_lo_i128(val)); | |
| 1504 | int64_t lo = zig_wrap_i64((int64_t)zig_lo_i128(val), bits); | |
| 1505 | return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo); | |
| 1642 | 1506 | } |
| 1643 | 1507 | |
| 1644 | 1508 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) { |
| ... | ... | @@ -1909,6 +1773,972 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { |
| 1909 | 1773 | return zig_bitcast_i128(zig_bit_reverse_u128(zig_bitcast_u128(val), bits)); |
| 1910 | 1774 | } |
| 1911 | 1775 | |
| 1776 | /* ========================== Big Integer Support =========================== */ | |
| 1777 | ||
| 1778 | static inline uint16_t zig_int_bytes(uint16_t bits) { | |
| 1779 | uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT; | |
| 1780 | uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT; | |
| 1781 | while (alignment / 2 >= bytes) alignment /= 2; | |
| 1782 | return (bytes + alignment - 1) / alignment * alignment; | |
| 1783 | } | |
| 1784 | ||
| 1785 | static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | |
| 1786 | const uint8_t *lhs_bytes = lhs; | |
| 1787 | const uint8_t *rhs_bytes = rhs; | |
| 1788 | uint16_t byte_offset = 0; | |
| 1789 | bool do_signed = is_signed; | |
| 1790 | uint16_t remaining_bytes = zig_int_bytes(bits); | |
| 1791 | ||
| 1792 | #if zig_little_endian | |
| 1793 | byte_offset = remaining_bytes; | |
| 1794 | #endif | |
| 1795 | ||
| 1796 | while (remaining_bytes >= 128 / CHAR_BIT) { | |
| 1797 | int32_t limb_cmp; | |
| 1798 | ||
| 1799 | #if zig_little_endian | |
| 1800 | byte_offset -= 128 / CHAR_BIT; | |
| 1801 | #endif | |
| 1802 | ||
| 1803 | if (do_signed) { | |
| 1804 | zig_i128 lhs_limb; | |
| 1805 | zig_i128 rhs_limb; | |
| 1806 | ||
| 1807 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1808 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1809 | limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb); | |
| 1810 | do_signed = false; | |
| 1811 | } else { | |
| 1812 | zig_u128 lhs_limb; | |
| 1813 | zig_u128 rhs_limb; | |
| 1814 | ||
| 1815 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1816 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1817 | limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb); | |
| 1818 | } | |
| 1819 | ||
| 1820 | if (limb_cmp != 0) return limb_cmp; | |
| 1821 | remaining_bytes -= 128 / CHAR_BIT; | |
| 1822 | ||
| 1823 | #if zig_big_endian | |
| 1824 | byte_offset += 128 / CHAR_BIT; | |
| 1825 | #endif | |
| 1826 | } | |
| 1827 | ||
| 1828 | while (remaining_bytes >= 64 / CHAR_BIT) { | |
| 1829 | #if zig_little_endian | |
| 1830 | byte_offset -= 64 / CHAR_BIT; | |
| 1831 | #endif | |
| 1832 | ||
| 1833 | if (do_signed) { | |
| 1834 | int64_t lhs_limb; | |
| 1835 | int64_t rhs_limb; | |
| 1836 | ||
| 1837 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1838 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1839 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1840 | do_signed = false; | |
| 1841 | } else { | |
| 1842 | uint64_t lhs_limb; | |
| 1843 | uint64_t rhs_limb; | |
| 1844 | ||
| 1845 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1846 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1847 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1848 | } | |
| 1849 | ||
| 1850 | remaining_bytes -= 64 / CHAR_BIT; | |
| 1851 | ||
| 1852 | #if zig_big_endian | |
| 1853 | byte_offset += 64 / CHAR_BIT; | |
| 1854 | #endif | |
| 1855 | } | |
| 1856 | ||
| 1857 | while (remaining_bytes >= 32 / CHAR_BIT) { | |
| 1858 | #if zig_little_endian | |
| 1859 | byte_offset -= 32 / CHAR_BIT; | |
| 1860 | #endif | |
| 1861 | ||
| 1862 | if (do_signed) { | |
| 1863 | int32_t lhs_limb; | |
| 1864 | int32_t rhs_limb; | |
| 1865 | ||
| 1866 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1867 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1868 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1869 | do_signed = false; | |
| 1870 | } else { | |
| 1871 | uint32_t lhs_limb; | |
| 1872 | uint32_t rhs_limb; | |
| 1873 | ||
| 1874 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1875 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1876 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1877 | } | |
| 1878 | ||
| 1879 | remaining_bytes -= 32 / CHAR_BIT; | |
| 1880 | ||
| 1881 | #if zig_big_endian | |
| 1882 | byte_offset += 32 / CHAR_BIT; | |
| 1883 | #endif | |
| 1884 | } | |
| 1885 | ||
| 1886 | while (remaining_bytes >= 16 / CHAR_BIT) { | |
| 1887 | #if zig_little_endian | |
| 1888 | byte_offset -= 16 / CHAR_BIT; | |
| 1889 | #endif | |
| 1890 | ||
| 1891 | if (do_signed) { | |
| 1892 | int16_t lhs_limb; | |
| 1893 | int16_t rhs_limb; | |
| 1894 | ||
| 1895 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1896 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1897 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1898 | do_signed = false; | |
| 1899 | } else { | |
| 1900 | uint16_t lhs_limb; | |
| 1901 | uint16_t rhs_limb; | |
| 1902 | ||
| 1903 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1904 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1905 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1906 | } | |
| 1907 | ||
| 1908 | remaining_bytes -= 16 / CHAR_BIT; | |
| 1909 | ||
| 1910 | #if zig_big_endian | |
| 1911 | byte_offset += 16 / CHAR_BIT; | |
| 1912 | #endif | |
| 1913 | } | |
| 1914 | ||
| 1915 | while (remaining_bytes >= 8 / CHAR_BIT) { | |
| 1916 | #if zig_little_endian | |
| 1917 | byte_offset -= 8 / CHAR_BIT; | |
| 1918 | #endif | |
| 1919 | ||
| 1920 | if (do_signed) { | |
| 1921 | int8_t lhs_limb; | |
| 1922 | int8_t rhs_limb; | |
| 1923 | ||
| 1924 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1925 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1926 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1927 | do_signed = false; | |
| 1928 | } else { | |
| 1929 | uint8_t lhs_limb; | |
| 1930 | uint8_t rhs_limb; | |
| 1931 | ||
| 1932 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1933 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1934 | if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb); | |
| 1935 | } | |
| 1936 | ||
| 1937 | remaining_bytes -= 8 / CHAR_BIT; | |
| 1938 | ||
| 1939 | #if zig_big_endian | |
| 1940 | byte_offset += 8 / CHAR_BIT; | |
| 1941 | #endif | |
| 1942 | } | |
| 1943 | ||
| 1944 | return 0; | |
| 1945 | } | |
| 1946 | ||
| 1947 | static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | |
| 1948 | uint8_t *res_bytes = res; | |
| 1949 | const uint8_t *lhs_bytes = lhs; | |
| 1950 | const uint8_t *rhs_bytes = rhs; | |
| 1951 | uint16_t byte_offset = 0; | |
| 1952 | uint16_t remaining_bytes = zig_int_bytes(bits); | |
| 1953 | uint16_t top_bits = remaining_bytes * 8 - bits; | |
| 1954 | bool overflow = false; | |
| 1955 | ||
| 1956 | #if zig_big_endian | |
| 1957 | byte_offset = remaining_bytes; | |
| 1958 | #endif | |
| 1959 | ||
| 1960 | while (remaining_bytes >= 128 / CHAR_BIT) { | |
| 1961 | uint16_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | |
| 1962 | ||
| 1963 | #if zig_big_endian | |
| 1964 | byte_offset -= 128 / CHAR_BIT; | |
| 1965 | #endif | |
| 1966 | ||
| 1967 | if (remaining_bytes == 128 / CHAR_BIT && is_signed) { | |
| 1968 | zig_i128 res_limb; | |
| 1969 | zig_i128 tmp_limb; | |
| 1970 | zig_i128 lhs_limb; | |
| 1971 | zig_i128 rhs_limb; | |
| 1972 | bool limb_overflow; | |
| 1973 | ||
| 1974 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1975 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1976 | limb_overflow = zig_addo_i128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 1977 | overflow = limb_overflow ^ zig_addo_i128(&res_limb, tmp_limb, zig_make_i128(INT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); | |
| 1978 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 1979 | } else { | |
| 1980 | zig_u128 res_limb; | |
| 1981 | zig_u128 tmp_limb; | |
| 1982 | zig_u128 lhs_limb; | |
| 1983 | zig_u128 rhs_limb; | |
| 1984 | bool limb_overflow; | |
| 1985 | ||
| 1986 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 1987 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 1988 | limb_overflow = zig_addo_u128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 1989 | overflow = limb_overflow ^ zig_addo_u128(&res_limb, tmp_limb, zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); | |
| 1990 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 1991 | } | |
| 1992 | ||
| 1993 | remaining_bytes -= 128 / CHAR_BIT; | |
| 1994 | ||
| 1995 | #if zig_little_endian | |
| 1996 | byte_offset += 128 / CHAR_BIT; | |
| 1997 | #endif | |
| 1998 | } | |
| 1999 | ||
| 2000 | while (remaining_bytes >= 64 / CHAR_BIT) { | |
| 2001 | uint16_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | |
| 2002 | ||
| 2003 | #if zig_big_endian | |
| 2004 | byte_offset -= 64 / CHAR_BIT; | |
| 2005 | #endif | |
| 2006 | ||
| 2007 | if (remaining_bytes == 64 / CHAR_BIT && is_signed) { | |
| 2008 | int64_t res_limb; | |
| 2009 | int64_t tmp_limb; | |
| 2010 | int64_t lhs_limb; | |
| 2011 | int64_t rhs_limb; | |
| 2012 | bool limb_overflow; | |
| 2013 | ||
| 2014 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2015 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2016 | limb_overflow = zig_addo_i64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2017 | overflow = limb_overflow ^ zig_addo_i64(&res_limb, tmp_limb, overflow ? INT64_C(1) : INT64_C(0), limb_bits); | |
| 2018 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2019 | } else { | |
| 2020 | uint64_t res_limb; | |
| 2021 | uint64_t tmp_limb; | |
| 2022 | uint64_t lhs_limb; | |
| 2023 | uint64_t rhs_limb; | |
| 2024 | bool limb_overflow; | |
| 2025 | ||
| 2026 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2027 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2028 | limb_overflow = zig_addo_u64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2029 | overflow = limb_overflow ^ zig_addo_u64(&res_limb, tmp_limb, overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); | |
| 2030 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2031 | } | |
| 2032 | ||
| 2033 | remaining_bytes -= 64 / CHAR_BIT; | |
| 2034 | ||
| 2035 | #if zig_little_endian | |
| 2036 | byte_offset += 64 / CHAR_BIT; | |
| 2037 | #endif | |
| 2038 | } | |
| 2039 | ||
| 2040 | while (remaining_bytes >= 32 / CHAR_BIT) { | |
| 2041 | uint16_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | |
| 2042 | ||
| 2043 | #if zig_big_endian | |
| 2044 | byte_offset -= 32 / CHAR_BIT; | |
| 2045 | #endif | |
| 2046 | ||
| 2047 | if (remaining_bytes == 32 / CHAR_BIT && is_signed) { | |
| 2048 | int32_t res_limb; | |
| 2049 | int32_t tmp_limb; | |
| 2050 | int32_t lhs_limb; | |
| 2051 | int32_t rhs_limb; | |
| 2052 | bool limb_overflow; | |
| 2053 | ||
| 2054 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2055 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2056 | limb_overflow = zig_addo_i32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2057 | overflow = limb_overflow ^ zig_addo_i32(&res_limb, tmp_limb, overflow ? INT32_C(1) : INT32_C(0), limb_bits); | |
| 2058 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2059 | } else { | |
| 2060 | uint32_t res_limb; | |
| 2061 | uint32_t tmp_limb; | |
| 2062 | uint32_t lhs_limb; | |
| 2063 | uint32_t rhs_limb; | |
| 2064 | bool limb_overflow; | |
| 2065 | ||
| 2066 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2067 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2068 | limb_overflow = zig_addo_u32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2069 | overflow = limb_overflow ^ zig_addo_u32(&res_limb, tmp_limb, overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); | |
| 2070 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2071 | } | |
| 2072 | ||
| 2073 | remaining_bytes -= 32 / CHAR_BIT; | |
| 2074 | ||
| 2075 | #if zig_little_endian | |
| 2076 | byte_offset += 32 / CHAR_BIT; | |
| 2077 | #endif | |
| 2078 | } | |
| 2079 | ||
| 2080 | while (remaining_bytes >= 16 / CHAR_BIT) { | |
| 2081 | uint16_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | |
| 2082 | ||
| 2083 | #if zig_big_endian | |
| 2084 | byte_offset -= 16 / CHAR_BIT; | |
| 2085 | #endif | |
| 2086 | ||
| 2087 | if (remaining_bytes == 16 / CHAR_BIT && is_signed) { | |
| 2088 | int16_t res_limb; | |
| 2089 | int16_t tmp_limb; | |
| 2090 | int16_t lhs_limb; | |
| 2091 | int16_t rhs_limb; | |
| 2092 | bool limb_overflow; | |
| 2093 | ||
| 2094 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2095 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2096 | limb_overflow = zig_addo_i16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2097 | overflow = limb_overflow ^ zig_addo_i16(&res_limb, tmp_limb, overflow ? INT16_C(1) : INT16_C(0), limb_bits); | |
| 2098 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2099 | } else { | |
| 2100 | uint16_t res_limb; | |
| 2101 | uint16_t tmp_limb; | |
| 2102 | uint16_t lhs_limb; | |
| 2103 | uint16_t rhs_limb; | |
| 2104 | bool limb_overflow; | |
| 2105 | ||
| 2106 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2107 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2108 | limb_overflow = zig_addo_u16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2109 | overflow = limb_overflow ^ zig_addo_u16(&res_limb, tmp_limb, overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); | |
| 2110 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2111 | } | |
| 2112 | ||
| 2113 | remaining_bytes -= 16 / CHAR_BIT; | |
| 2114 | ||
| 2115 | #if zig_little_endian | |
| 2116 | byte_offset += 16 / CHAR_BIT; | |
| 2117 | #endif | |
| 2118 | } | |
| 2119 | ||
| 2120 | while (remaining_bytes >= 8 / CHAR_BIT) { | |
| 2121 | uint16_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | |
| 2122 | ||
| 2123 | #if zig_big_endian | |
| 2124 | byte_offset -= 8 / CHAR_BIT; | |
| 2125 | #endif | |
| 2126 | ||
| 2127 | if (remaining_bytes == 8 / CHAR_BIT && is_signed) { | |
| 2128 | int8_t res_limb; | |
| 2129 | int8_t tmp_limb; | |
| 2130 | int8_t lhs_limb; | |
| 2131 | int8_t rhs_limb; | |
| 2132 | bool limb_overflow; | |
| 2133 | ||
| 2134 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2135 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2136 | limb_overflow = zig_addo_i8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2137 | overflow = limb_overflow ^ zig_addo_i8(&res_limb, tmp_limb, overflow ? INT8_C(1) : INT8_C(0), limb_bits); | |
| 2138 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2139 | } else { | |
| 2140 | uint8_t res_limb; | |
| 2141 | uint8_t tmp_limb; | |
| 2142 | uint8_t lhs_limb; | |
| 2143 | uint8_t rhs_limb; | |
| 2144 | bool limb_overflow; | |
| 2145 | ||
| 2146 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2147 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2148 | limb_overflow = zig_addo_u8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2149 | overflow = limb_overflow ^ zig_addo_u8(&res_limb, tmp_limb, overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); | |
| 2150 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2151 | } | |
| 2152 | ||
| 2153 | remaining_bytes -= 8 / CHAR_BIT; | |
| 2154 | ||
| 2155 | #if zig_little_endian | |
| 2156 | byte_offset += 8 / CHAR_BIT; | |
| 2157 | #endif | |
| 2158 | } | |
| 2159 | ||
| 2160 | return overflow; | |
| 2161 | } | |
| 2162 | ||
| 2163 | static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | |
| 2164 | uint8_t *res_bytes = res; | |
| 2165 | const uint8_t *lhs_bytes = lhs; | |
| 2166 | const uint8_t *rhs_bytes = rhs; | |
| 2167 | uint16_t byte_offset = 0; | |
| 2168 | uint16_t remaining_bytes = zig_int_bytes(bits); | |
| 2169 | uint16_t top_bits = remaining_bytes * 8 - bits; | |
| 2170 | bool overflow = false; | |
| 2171 | ||
| 2172 | #if zig_big_endian | |
| 2173 | byte_offset = remaining_bytes; | |
| 2174 | #endif | |
| 2175 | ||
| 2176 | while (remaining_bytes >= 128 / CHAR_BIT) { | |
| 2177 | uint16_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); | |
| 2178 | ||
| 2179 | #if zig_big_endian | |
| 2180 | byte_offset -= 128 / CHAR_BIT; | |
| 2181 | #endif | |
| 2182 | ||
| 2183 | if (remaining_bytes == 128 / CHAR_BIT && is_signed) { | |
| 2184 | zig_i128 res_limb; | |
| 2185 | zig_i128 tmp_limb; | |
| 2186 | zig_i128 lhs_limb; | |
| 2187 | zig_i128 rhs_limb; | |
| 2188 | bool limb_overflow; | |
| 2189 | ||
| 2190 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2191 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2192 | limb_overflow = zig_subo_i128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2193 | overflow = limb_overflow ^ zig_subo_i128(&res_limb, tmp_limb, zig_make_i128(INT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); | |
| 2194 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2195 | } else { | |
| 2196 | zig_u128 res_limb; | |
| 2197 | zig_u128 tmp_limb; | |
| 2198 | zig_u128 lhs_limb; | |
| 2199 | zig_u128 rhs_limb; | |
| 2200 | bool limb_overflow; | |
| 2201 | ||
| 2202 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2203 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2204 | limb_overflow = zig_subo_u128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2205 | overflow = limb_overflow ^ zig_subo_u128(&res_limb, tmp_limb, zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); | |
| 2206 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2207 | } | |
| 2208 | ||
| 2209 | remaining_bytes -= 128 / CHAR_BIT; | |
| 2210 | ||
| 2211 | #if zig_little_endian | |
| 2212 | byte_offset += 128 / CHAR_BIT; | |
| 2213 | #endif | |
| 2214 | } | |
| 2215 | ||
| 2216 | while (remaining_bytes >= 64 / CHAR_BIT) { | |
| 2217 | uint16_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); | |
| 2218 | ||
| 2219 | #if zig_big_endian | |
| 2220 | byte_offset -= 64 / CHAR_BIT; | |
| 2221 | #endif | |
| 2222 | ||
| 2223 | if (remaining_bytes == 64 / CHAR_BIT && is_signed) { | |
| 2224 | int64_t res_limb; | |
| 2225 | int64_t tmp_limb; | |
| 2226 | int64_t lhs_limb; | |
| 2227 | int64_t rhs_limb; | |
| 2228 | bool limb_overflow; | |
| 2229 | ||
| 2230 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2231 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2232 | limb_overflow = zig_subo_i64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2233 | overflow = limb_overflow ^ zig_subo_i64(&res_limb, tmp_limb, overflow ? INT64_C(1) : INT64_C(0), limb_bits); | |
| 2234 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2235 | } else { | |
| 2236 | uint64_t res_limb; | |
| 2237 | uint64_t tmp_limb; | |
| 2238 | uint64_t lhs_limb; | |
| 2239 | uint64_t rhs_limb; | |
| 2240 | bool limb_overflow; | |
| 2241 | ||
| 2242 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2243 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2244 | limb_overflow = zig_subo_u64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2245 | overflow = limb_overflow ^ zig_subo_u64(&res_limb, tmp_limb, overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); | |
| 2246 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2247 | } | |
| 2248 | ||
| 2249 | remaining_bytes -= 64 / CHAR_BIT; | |
| 2250 | ||
| 2251 | #if zig_little_endian | |
| 2252 | byte_offset += 64 / CHAR_BIT; | |
| 2253 | #endif | |
| 2254 | } | |
| 2255 | ||
| 2256 | while (remaining_bytes >= 32 / CHAR_BIT) { | |
| 2257 | uint16_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); | |
| 2258 | ||
| 2259 | #if zig_big_endian | |
| 2260 | byte_offset -= 32 / CHAR_BIT; | |
| 2261 | #endif | |
| 2262 | ||
| 2263 | if (remaining_bytes == 32 / CHAR_BIT && is_signed) { | |
| 2264 | int32_t res_limb; | |
| 2265 | int32_t tmp_limb; | |
| 2266 | int32_t lhs_limb; | |
| 2267 | int32_t rhs_limb; | |
| 2268 | bool limb_overflow; | |
| 2269 | ||
| 2270 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2271 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2272 | limb_overflow = zig_subo_i32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2273 | overflow = limb_overflow ^ zig_subo_i32(&res_limb, tmp_limb, overflow ? INT32_C(1) : INT32_C(0), limb_bits); | |
| 2274 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2275 | } else { | |
| 2276 | uint32_t res_limb; | |
| 2277 | uint32_t tmp_limb; | |
| 2278 | uint32_t lhs_limb; | |
| 2279 | uint32_t rhs_limb; | |
| 2280 | bool limb_overflow; | |
| 2281 | ||
| 2282 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2283 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2284 | limb_overflow = zig_subo_u32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2285 | overflow = limb_overflow ^ zig_subo_u32(&res_limb, tmp_limb, overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); | |
| 2286 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2287 | } | |
| 2288 | ||
| 2289 | remaining_bytes -= 32 / CHAR_BIT; | |
| 2290 | ||
| 2291 | #if zig_little_endian | |
| 2292 | byte_offset += 32 / CHAR_BIT; | |
| 2293 | #endif | |
| 2294 | } | |
| 2295 | ||
| 2296 | while (remaining_bytes >= 16 / CHAR_BIT) { | |
| 2297 | uint16_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); | |
| 2298 | ||
| 2299 | #if zig_big_endian | |
| 2300 | byte_offset -= 16 / CHAR_BIT; | |
| 2301 | #endif | |
| 2302 | ||
| 2303 | if (remaining_bytes == 16 / CHAR_BIT && is_signed) { | |
| 2304 | int16_t res_limb; | |
| 2305 | int16_t tmp_limb; | |
| 2306 | int16_t lhs_limb; | |
| 2307 | int16_t rhs_limb; | |
| 2308 | bool limb_overflow; | |
| 2309 | ||
| 2310 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2311 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2312 | limb_overflow = zig_subo_i16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2313 | overflow = limb_overflow ^ zig_subo_i16(&res_limb, tmp_limb, overflow ? INT16_C(1) : INT16_C(0), limb_bits); | |
| 2314 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2315 | } else { | |
| 2316 | uint16_t res_limb; | |
| 2317 | uint16_t tmp_limb; | |
| 2318 | uint16_t lhs_limb; | |
| 2319 | uint16_t rhs_limb; | |
| 2320 | bool limb_overflow; | |
| 2321 | ||
| 2322 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2323 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2324 | limb_overflow = zig_subo_u16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2325 | overflow = limb_overflow ^ zig_subo_u16(&res_limb, tmp_limb, overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); | |
| 2326 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2327 | } | |
| 2328 | ||
| 2329 | remaining_bytes -= 16 / CHAR_BIT; | |
| 2330 | ||
| 2331 | #if zig_little_endian | |
| 2332 | byte_offset += 16 / CHAR_BIT; | |
| 2333 | #endif | |
| 2334 | } | |
| 2335 | ||
| 2336 | while (remaining_bytes >= 8 / CHAR_BIT) { | |
| 2337 | uint16_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); | |
| 2338 | ||
| 2339 | #if zig_big_endian | |
| 2340 | byte_offset -= 8 / CHAR_BIT; | |
| 2341 | #endif | |
| 2342 | ||
| 2343 | if (remaining_bytes == 8 / CHAR_BIT && is_signed) { | |
| 2344 | int8_t res_limb; | |
| 2345 | int8_t tmp_limb; | |
| 2346 | int8_t lhs_limb; | |
| 2347 | int8_t rhs_limb; | |
| 2348 | bool limb_overflow; | |
| 2349 | ||
| 2350 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2351 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2352 | limb_overflow = zig_subo_i8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2353 | overflow = limb_overflow ^ zig_subo_i8(&res_limb, tmp_limb, overflow ? INT8_C(1) : INT8_C(0), limb_bits); | |
| 2354 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2355 | } else { | |
| 2356 | uint8_t res_limb; | |
| 2357 | uint8_t tmp_limb; | |
| 2358 | uint8_t lhs_limb; | |
| 2359 | uint8_t rhs_limb; | |
| 2360 | bool limb_overflow; | |
| 2361 | ||
| 2362 | memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); | |
| 2363 | memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); | |
| 2364 | limb_overflow = zig_subo_u8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); | |
| 2365 | overflow = limb_overflow ^ zig_subo_u8(&res_limb, tmp_limb, overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); | |
| 2366 | memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); | |
| 2367 | } | |
| 2368 | ||
| 2369 | remaining_bytes -= 8 / CHAR_BIT; | |
| 2370 | ||
| 2371 | #if zig_little_endian | |
| 2372 | byte_offset += 8 / CHAR_BIT; | |
| 2373 | #endif | |
| 2374 | } | |
| 2375 | ||
| 2376 | return overflow; | |
| 2377 | } | |
| 2378 | ||
| 2379 | static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | |
| 2380 | (void)zig_addo_big(res, lhs, rhs, is_signed, bits); | |
| 2381 | } | |
| 2382 | ||
| 2383 | static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { | |
| 2384 | (void)zig_subo_big(res, lhs, rhs, is_signed, bits); | |
| 2385 | } | |
| 2386 | ||
| 2387 | static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) { | |
| 2388 | const uint8_t *val_bytes = val; | |
| 2389 | uint16_t byte_offset = 0; | |
| 2390 | uint16_t remaining_bytes = zig_int_bytes(bits); | |
| 2391 | uint16_t skip_bits = remaining_bytes * 8 - bits; | |
| 2392 | uint16_t total_lz = 0; | |
| 2393 | uint16_t limb_lz; | |
| 2394 | (void)is_signed; | |
| 2395 | ||
| 2396 | #if zig_little_endian | |
| 2397 | byte_offset = remaining_bytes; | |
| 2398 | #endif | |
| 2399 | ||
| 2400 | while (remaining_bytes >= 128 / CHAR_BIT) { | |
| 2401 | #if zig_little_endian | |
| 2402 | byte_offset -= 128 / CHAR_BIT; | |
| 2403 | #endif | |
| 2404 | ||
| 2405 | { | |
| 2406 | zig_u128 val_limb; | |
| 2407 | ||
| 2408 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2409 | limb_lz = zig_clz_u128(val_limb, 128 - skip_bits); | |
| 2410 | } | |
| 2411 | ||
| 2412 | total_lz += limb_lz; | |
| 2413 | if (limb_lz < 128 - skip_bits) return total_lz; | |
| 2414 | skip_bits = 0; | |
| 2415 | remaining_bytes -= 128 / CHAR_BIT; | |
| 2416 | ||
| 2417 | #if zig_big_endian | |
| 2418 | byte_offset += 128 / CHAR_BIT; | |
| 2419 | #endif | |
| 2420 | } | |
| 2421 | ||
| 2422 | while (remaining_bytes >= 64 / CHAR_BIT) { | |
| 2423 | #if zig_little_endian | |
| 2424 | byte_offset -= 64 / CHAR_BIT; | |
| 2425 | #endif | |
| 2426 | ||
| 2427 | { | |
| 2428 | uint64_t val_limb; | |
| 2429 | ||
| 2430 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2431 | limb_lz = zig_clz_u64(val_limb, 64 - skip_bits); | |
| 2432 | } | |
| 2433 | ||
| 2434 | total_lz += limb_lz; | |
| 2435 | if (limb_lz < 64 - skip_bits) return total_lz; | |
| 2436 | skip_bits = 0; | |
| 2437 | remaining_bytes -= 64 / CHAR_BIT; | |
| 2438 | ||
| 2439 | #if zig_big_endian | |
| 2440 | byte_offset += 64 / CHAR_BIT; | |
| 2441 | #endif | |
| 2442 | } | |
| 2443 | ||
| 2444 | while (remaining_bytes >= 32 / CHAR_BIT) { | |
| 2445 | #if zig_little_endian | |
| 2446 | byte_offset -= 32 / CHAR_BIT; | |
| 2447 | #endif | |
| 2448 | ||
| 2449 | { | |
| 2450 | uint32_t val_limb; | |
| 2451 | ||
| 2452 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2453 | limb_lz = zig_clz_u32(val_limb, 32 - skip_bits); | |
| 2454 | } | |
| 2455 | ||
| 2456 | total_lz += limb_lz; | |
| 2457 | if (limb_lz < 32 - skip_bits) return total_lz; | |
| 2458 | skip_bits = 0; | |
| 2459 | remaining_bytes -= 32 / CHAR_BIT; | |
| 2460 | ||
| 2461 | #if zig_big_endian | |
| 2462 | byte_offset += 32 / CHAR_BIT; | |
| 2463 | #endif | |
| 2464 | } | |
| 2465 | ||
| 2466 | while (remaining_bytes >= 16 / CHAR_BIT) { | |
| 2467 | #if zig_little_endian | |
| 2468 | byte_offset -= 16 / CHAR_BIT; | |
| 2469 | #endif | |
| 2470 | ||
| 2471 | { | |
| 2472 | uint16_t val_limb; | |
| 2473 | ||
| 2474 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2475 | limb_lz = zig_clz_u16(val_limb, 16 - skip_bits); | |
| 2476 | } | |
| 2477 | ||
| 2478 | total_lz += limb_lz; | |
| 2479 | if (limb_lz < 16 - skip_bits) return total_lz; | |
| 2480 | skip_bits = 0; | |
| 2481 | remaining_bytes -= 16 / CHAR_BIT; | |
| 2482 | ||
| 2483 | #if zig_big_endian | |
| 2484 | byte_offset += 16 / CHAR_BIT; | |
| 2485 | #endif | |
| 2486 | } | |
| 2487 | ||
| 2488 | while (remaining_bytes >= 8 / CHAR_BIT) { | |
| 2489 | #if zig_little_endian | |
| 2490 | byte_offset -= 8 / CHAR_BIT; | |
| 2491 | #endif | |
| 2492 | ||
| 2493 | { | |
| 2494 | uint8_t val_limb; | |
| 2495 | ||
| 2496 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2497 | limb_lz = zig_clz_u8(val_limb, 8 - skip_bits); | |
| 2498 | } | |
| 2499 | ||
| 2500 | total_lz += limb_lz; | |
| 2501 | if (limb_lz < 8 - skip_bits) return total_lz; | |
| 2502 | skip_bits = 0; | |
| 2503 | remaining_bytes -= 8 / CHAR_BIT; | |
| 2504 | ||
| 2505 | #if zig_big_endian | |
| 2506 | byte_offset += 8 / CHAR_BIT; | |
| 2507 | #endif | |
| 2508 | } | |
| 2509 | ||
| 2510 | return total_lz; | |
| 2511 | } | |
| 2512 | ||
| 2513 | static inline uint16_t zig_ctz_big(const void *val, bool is_signed, uint16_t bits) { | |
| 2514 | const uint8_t *val_bytes = val; | |
| 2515 | uint16_t byte_offset = 0; | |
| 2516 | uint16_t remaining_bytes = zig_int_bytes(bits); | |
| 2517 | uint16_t total_tz = 0; | |
| 2518 | uint16_t limb_tz; | |
| 2519 | (void)is_signed; | |
| 2520 | ||
| 2521 | #if zig_big_endian | |
| 2522 | byte_offset = remaining_bytes; | |
| 2523 | #endif | |
| 2524 | ||
| 2525 | while (remaining_bytes >= 128 / CHAR_BIT) { | |
| 2526 | #if zig_big_endian | |
| 2527 | byte_offset -= 128 / CHAR_BIT; | |
| 2528 | #endif | |
| 2529 | ||
| 2530 | { | |
| 2531 | zig_u128 val_limb; | |
| 2532 | ||
| 2533 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2534 | limb_tz = zig_ctz_u128(val_limb, 128); | |
| 2535 | } | |
| 2536 | ||
| 2537 | total_tz += limb_tz; | |
| 2538 | if (limb_tz < 128) return total_tz; | |
| 2539 | remaining_bytes -= 128 / CHAR_BIT; | |
| 2540 | ||
| 2541 | #if zig_little_endian | |
| 2542 | byte_offset += 128 / CHAR_BIT; | |
| 2543 | #endif | |
| 2544 | } | |
| 2545 | ||
| 2546 | while (remaining_bytes >= 64 / CHAR_BIT) { | |
| 2547 | #if zig_big_endian | |
| 2548 | byte_offset -= 64 / CHAR_BIT; | |
| 2549 | #endif | |
| 2550 | ||
| 2551 | { | |
| 2552 | uint64_t val_limb; | |
| 2553 | ||
| 2554 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2555 | limb_tz = zig_ctz_u64(val_limb, 64); | |
| 2556 | } | |
| 2557 | ||
| 2558 | total_tz += limb_tz; | |
| 2559 | if (limb_tz < 64) return total_tz; | |
| 2560 | remaining_bytes -= 64 / CHAR_BIT; | |
| 2561 | ||
| 2562 | #if zig_little_endian | |
| 2563 | byte_offset += 64 / CHAR_BIT; | |
| 2564 | #endif | |
| 2565 | } | |
| 2566 | ||
| 2567 | while (remaining_bytes >= 32 / CHAR_BIT) { | |
| 2568 | #if zig_big_endian | |
| 2569 | byte_offset -= 32 / CHAR_BIT; | |
| 2570 | #endif | |
| 2571 | ||
| 2572 | { | |
| 2573 | uint32_t val_limb; | |
| 2574 | ||
| 2575 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2576 | limb_tz = zig_ctz_u32(val_limb, 32); | |
| 2577 | } | |
| 2578 | ||
| 2579 | total_tz += limb_tz; | |
| 2580 | if (limb_tz < 32) return total_tz; | |
| 2581 | remaining_bytes -= 32 / CHAR_BIT; | |
| 2582 | ||
| 2583 | #if zig_little_endian | |
| 2584 | byte_offset += 32 / CHAR_BIT; | |
| 2585 | #endif | |
| 2586 | } | |
| 2587 | ||
| 2588 | while (remaining_bytes >= 16 / CHAR_BIT) { | |
| 2589 | #if zig_big_endian | |
| 2590 | byte_offset -= 16 / CHAR_BIT; | |
| 2591 | #endif | |
| 2592 | ||
| 2593 | { | |
| 2594 | uint16_t val_limb; | |
| 2595 | ||
| 2596 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2597 | limb_tz = zig_ctz_u16(val_limb, 16); | |
| 2598 | } | |
| 2599 | ||
| 2600 | total_tz += limb_tz; | |
| 2601 | if (limb_tz < 16) return total_tz; | |
| 2602 | remaining_bytes -= 16 / CHAR_BIT; | |
| 2603 | ||
| 2604 | #if zig_little_endian | |
| 2605 | byte_offset += 16 / CHAR_BIT; | |
| 2606 | #endif | |
| 2607 | } | |
| 2608 | ||
| 2609 | while (remaining_bytes >= 8 / CHAR_BIT) { | |
| 2610 | #if zig_big_endian | |
| 2611 | byte_offset -= 8 / CHAR_BIT; | |
| 2612 | #endif | |
| 2613 | ||
| 2614 | { | |
| 2615 | uint8_t val_limb; | |
| 2616 | ||
| 2617 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2618 | limb_tz = zig_ctz_u8(val_limb, 8); | |
| 2619 | } | |
| 2620 | ||
| 2621 | total_tz += limb_tz; | |
| 2622 | if (limb_tz < 8) return total_tz; | |
| 2623 | remaining_bytes -= 8 / CHAR_BIT; | |
| 2624 | ||
| 2625 | #if zig_little_endian | |
| 2626 | byte_offset += 8 / CHAR_BIT; | |
| 2627 | #endif | |
| 2628 | } | |
| 2629 | ||
| 2630 | return total_tz; | |
| 2631 | } | |
| 2632 | ||
| 2633 | static inline uint16_t zig_popcount_big(const void *val, bool is_signed, uint16_t bits) { | |
| 2634 | const uint8_t *val_bytes = val; | |
| 2635 | uint16_t byte_offset = 0; | |
| 2636 | uint16_t remaining_bytes = zig_int_bytes(bits); | |
| 2637 | uint16_t total_pc = 0; | |
| 2638 | (void)is_signed; | |
| 2639 | ||
| 2640 | #if zig_big_endian | |
| 2641 | byte_offset = remaining_bytes; | |
| 2642 | #endif | |
| 2643 | ||
| 2644 | while (remaining_bytes >= 128 / CHAR_BIT) { | |
| 2645 | #if zig_big_endian | |
| 2646 | byte_offset -= 128 / CHAR_BIT; | |
| 2647 | #endif | |
| 2648 | ||
| 2649 | { | |
| 2650 | zig_u128 val_limb; | |
| 2651 | ||
| 2652 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2653 | total_pc += zig_popcount_u128(val_limb, 128); | |
| 2654 | } | |
| 2655 | ||
| 2656 | remaining_bytes -= 128 / CHAR_BIT; | |
| 2657 | ||
| 2658 | #if zig_little_endian | |
| 2659 | byte_offset += 128 / CHAR_BIT; | |
| 2660 | #endif | |
| 2661 | } | |
| 2662 | ||
| 2663 | while (remaining_bytes >= 64 / CHAR_BIT) { | |
| 2664 | #if zig_big_endian | |
| 2665 | byte_offset -= 64 / CHAR_BIT; | |
| 2666 | #endif | |
| 2667 | ||
| 2668 | { | |
| 2669 | uint64_t val_limb; | |
| 2670 | ||
| 2671 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2672 | total_pc += zig_popcount_u64(val_limb, 64); | |
| 2673 | } | |
| 2674 | ||
| 2675 | remaining_bytes -= 64 / CHAR_BIT; | |
| 2676 | ||
| 2677 | #if zig_little_endian | |
| 2678 | byte_offset += 64 / CHAR_BIT; | |
| 2679 | #endif | |
| 2680 | } | |
| 2681 | ||
| 2682 | while (remaining_bytes >= 32 / CHAR_BIT) { | |
| 2683 | #if zig_big_endian | |
| 2684 | byte_offset -= 32 / CHAR_BIT; | |
| 2685 | #endif | |
| 2686 | ||
| 2687 | { | |
| 2688 | uint32_t val_limb; | |
| 2689 | ||
| 2690 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2691 | total_pc += zig_popcount_u32(val_limb, 32); | |
| 2692 | } | |
| 2693 | ||
| 2694 | remaining_bytes -= 32 / CHAR_BIT; | |
| 2695 | ||
| 2696 | #if zig_little_endian | |
| 2697 | byte_offset += 32 / CHAR_BIT; | |
| 2698 | #endif | |
| 2699 | } | |
| 2700 | ||
| 2701 | while (remaining_bytes >= 16 / CHAR_BIT) { | |
| 2702 | #if zig_big_endian | |
| 2703 | byte_offset -= 16 / CHAR_BIT; | |
| 2704 | #endif | |
| 2705 | ||
| 2706 | { | |
| 2707 | uint16_t val_limb; | |
| 2708 | ||
| 2709 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2710 | total_pc = zig_popcount_u16(val_limb, 16); | |
| 2711 | } | |
| 2712 | ||
| 2713 | remaining_bytes -= 16 / CHAR_BIT; | |
| 2714 | ||
| 2715 | #if zig_little_endian | |
| 2716 | byte_offset += 16 / CHAR_BIT; | |
| 2717 | #endif | |
| 2718 | } | |
| 2719 | ||
| 2720 | while (remaining_bytes >= 8 / CHAR_BIT) { | |
| 2721 | #if zig_big_endian | |
| 2722 | byte_offset -= 8 / CHAR_BIT; | |
| 2723 | #endif | |
| 2724 | ||
| 2725 | { | |
| 2726 | uint8_t val_limb; | |
| 2727 | ||
| 2728 | memcpy(&val_limb, &val_bytes[byte_offset], sizeof(val_limb)); | |
| 2729 | total_pc = zig_popcount_u8(val_limb, 8); | |
| 2730 | } | |
| 2731 | ||
| 2732 | remaining_bytes -= 8 / CHAR_BIT; | |
| 2733 | ||
| 2734 | #if zig_little_endian | |
| 2735 | byte_offset += 8 / CHAR_BIT; | |
| 2736 | #endif | |
| 2737 | } | |
| 2738 | ||
| 2739 | return total_pc; | |
| 2740 | } | |
| 2741 | ||
| 1912 | 2742 | /* ========================= Floating Point Support ========================= */ |
| 1913 | 2743 | |
| 1914 | 2744 | #if _MSC_VER |
| ... | ... | @@ -1933,7 +2763,6 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { |
| 1933 | 2763 | #define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64(__builtin_##name, )(arg) |
| 1934 | 2764 | #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80(__builtin_##name, )(arg) |
| 1935 | 2765 | #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) |
| 1936 | #define zig_make_special_c_longdouble(sign, name, arg, repr) sign zig_make_c_longdouble(__builtin_##name, )(arg) | |
| 1937 | 2766 | #else |
| 1938 | 2767 | #define zig_has_float_builtins 0 |
| 1939 | 2768 | #define zig_make_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr) |
| ... | ... | @@ -1941,13 +2770,13 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { |
| 1941 | 2770 | #define zig_make_special_f64(sign, name, arg, repr) zig_float_from_repr_f64(repr) |
| 1942 | 2771 | #define zig_make_special_f80(sign, name, arg, repr) zig_float_from_repr_f80(repr) |
| 1943 | 2772 | #define zig_make_special_f128(sign, name, arg, repr) zig_float_from_repr_f128(repr) |
| 1944 | #define zig_make_special_c_longdouble(sign, name, arg, repr) zig_float_from_repr_c_longdouble(repr) | |
| 1945 | 2773 | #endif |
| 1946 | 2774 | |
| 1947 | 2775 | #define zig_has_f16 1 |
| 1948 | 2776 | #define zig_bitSizeOf_f16 16 |
| 2777 | typedef int16_t zig_repr_f16; | |
| 1949 | 2778 | #define zig_libc_name_f16(name) __##name##h |
| 1950 | #define zig_make_special_constant_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) | |
| 2779 | #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) | |
| 1951 | 2780 | #if FLT_MANT_DIG == 11 |
| 1952 | 2781 | typedef float zig_f16; |
| 1953 | 2782 | #define zig_make_f16(fp, repr) fp##f |
| ... | ... | @@ -1956,7 +2785,9 @@ typedef double zig_f16; |
| 1956 | 2785 | #define zig_make_f16(fp, repr) fp |
| 1957 | 2786 | #elif LDBL_MANT_DIG == 11 |
| 1958 | 2787 | #define zig_bitSizeOf_c_longdouble 16 |
| 1959 | typedef uint16_t zig_repr_c_longdouble; | |
| 2788 | #ifndef ZIG_TARGET_ABI_MSVC | |
| 2789 | typedef zig_repr_f16 zig_repr_c_longdouble; | |
| 2790 | #endif | |
| 1960 | 2791 | typedef long double zig_f16; |
| 1961 | 2792 | #define zig_make_f16(fp, repr) fp##l |
| 1962 | 2793 | #elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc)) |
| ... | ... | @@ -1973,17 +2804,18 @@ typedef int16_t zig_f16; |
| 1973 | 2804 | #define zig_make_f16(fp, repr) repr |
| 1974 | 2805 | #undef zig_make_special_f16 |
| 1975 | 2806 | #define zig_make_special_f16(sign, name, arg, repr) repr |
| 1976 | #undef zig_make_special_constant_f16 | |
| 1977 | #define zig_make_special_constant_f16(sign, name, arg, repr) repr | |
| 2807 | #undef zig_init_special_f16 | |
| 2808 | #define zig_init_special_f16(sign, name, arg, repr) repr | |
| 1978 | 2809 | #endif |
| 1979 | 2810 | |
| 1980 | 2811 | #define zig_has_f32 1 |
| 1981 | 2812 | #define zig_bitSizeOf_f32 32 |
| 2813 | typedef int32_t zig_repr_f32; | |
| 1982 | 2814 | #define zig_libc_name_f32(name) name##f |
| 1983 | 2815 | #if _MSC_VER |
| 1984 | #define zig_make_special_constant_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, ) | |
| 2816 | #define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, ) | |
| 1985 | 2817 | #else |
| 1986 | #define zig_make_special_constant_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) | |
| 2818 | #define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) | |
| 1987 | 2819 | #endif |
| 1988 | 2820 | #if FLT_MANT_DIG == 24 |
| 1989 | 2821 | typedef float zig_f32; |
| ... | ... | @@ -1993,7 +2825,9 @@ typedef double zig_f32; |
| 1993 | 2825 | #define zig_make_f32(fp, repr) fp |
| 1994 | 2826 | #elif LDBL_MANT_DIG == 24 |
| 1995 | 2827 | #define zig_bitSizeOf_c_longdouble 32 |
| 1996 | typedef uint32_t zig_repr_c_longdouble; | |
| 2828 | #ifndef ZIG_TARGET_ABI_MSVC | |
| 2829 | typedef zig_repr_f32 zig_repr_c_longdouble; | |
| 2830 | #endif | |
| 1997 | 2831 | typedef long double zig_f32; |
| 1998 | 2832 | #define zig_make_f32(fp, repr) fp##l |
| 1999 | 2833 | #elif FLT32_MANT_DIG == 24 |
| ... | ... | @@ -2007,21 +2841,24 @@ typedef int32_t zig_f32; |
| 2007 | 2841 | #define zig_make_f32(fp, repr) repr |
| 2008 | 2842 | #undef zig_make_special_f32 |
| 2009 | 2843 | #define zig_make_special_f32(sign, name, arg, repr) repr |
| 2010 | #undef zig_make_special_constant_f32 | |
| 2011 | #define zig_make_special_constant_f32(sign, name, arg, repr) repr | |
| 2844 | #undef zig_init_special_f32 | |
| 2845 | #define zig_init_special_f32(sign, name, arg, repr) repr | |
| 2012 | 2846 | #endif |
| 2013 | 2847 | |
| 2014 | 2848 | #define zig_has_f64 1 |
| 2015 | 2849 | #define zig_bitSizeOf_f64 64 |
| 2850 | typedef int64_t zig_repr_f64; | |
| 2016 | 2851 | #define zig_libc_name_f64(name) name |
| 2017 | 2852 | #if _MSC_VER |
| 2018 | 2853 | #ifdef ZIG_TARGET_ABI_MSVC |
| 2019 | 2854 | #define zig_bitSizeOf_c_longdouble 64 |
| 2020 | typedef uint64_t zig_repr_c_longdouble; | |
| 2855 | #ifndef ZIG_TARGET_ABI_MSVC | |
| 2856 | typedef zig_repr_f64 zig_repr_c_longdouble; | |
| 2857 | #endif | |
| 2021 | 2858 | #endif |
| 2022 | #define zig_make_special_constant_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, ) | |
| 2859 | #define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, ) | |
| 2023 | 2860 | #else /* _MSC_VER */ |
| 2024 | #define zig_make_special_constant_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) | |
| 2861 | #define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) | |
| 2025 | 2862 | #endif /* _MSC_VER */ |
| 2026 | 2863 | #if FLT_MANT_DIG == 53 |
| 2027 | 2864 | typedef float zig_f64; |
| ... | ... | @@ -2031,7 +2868,9 @@ typedef double zig_f64; |
| 2031 | 2868 | #define zig_make_f64(fp, repr) fp |
| 2032 | 2869 | #elif LDBL_MANT_DIG == 53 |
| 2033 | 2870 | #define zig_bitSizeOf_c_longdouble 64 |
| 2034 | typedef uint64_t zig_repr_c_longdouble; | |
| 2871 | #ifndef ZIG_TARGET_ABI_MSVC | |
| 2872 | typedef zig_repr_f64 zig_repr_c_longdouble; | |
| 2873 | #endif | |
| 2035 | 2874 | typedef long double zig_f64; |
| 2036 | 2875 | #define zig_make_f64(fp, repr) fp##l |
| 2037 | 2876 | #elif FLT64_MANT_DIG == 53 |
| ... | ... | @@ -2048,14 +2887,15 @@ typedef int64_t zig_f64; |
| 2048 | 2887 | #define zig_make_f64(fp, repr) repr |
| 2049 | 2888 | #undef zig_make_special_f64 |
| 2050 | 2889 | #define zig_make_special_f64(sign, name, arg, repr) repr |
| 2051 | #undef zig_make_special_constant_f64 | |
| 2052 | #define zig_make_special_constant_f64(sign, name, arg, repr) repr | |
| 2890 | #undef zig_init_special_f64 | |
| 2891 | #define zig_init_special_f64(sign, name, arg, repr) repr | |
| 2053 | 2892 | #endif |
| 2054 | 2893 | |
| 2055 | 2894 | #define zig_has_f80 1 |
| 2056 | 2895 | #define zig_bitSizeOf_f80 80 |
| 2896 | typedef zig_i128 zig_repr_f80; | |
| 2057 | 2897 | #define zig_libc_name_f80(name) __##name##x |
| 2058 | #define zig_make_special_constant_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) | |
| 2898 | #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) | |
| 2059 | 2899 | #if FLT_MANT_DIG == 64 |
| 2060 | 2900 | typedef float zig_f80; |
| 2061 | 2901 | #define zig_make_f80(fp, repr) fp##f |
| ... | ... | @@ -2064,7 +2904,9 @@ typedef double zig_f80; |
| 2064 | 2904 | #define zig_make_f80(fp, repr) fp |
| 2065 | 2905 | #elif LDBL_MANT_DIG == 64 |
| 2066 | 2906 | #define zig_bitSizeOf_c_longdouble 80 |
| 2067 | typedef zig_u128 zig_repr_c_longdouble; | |
| 2907 | #ifndef ZIG_TARGET_ABI_MSVC | |
| 2908 | typedef zig_repr_f80 zig_repr_c_longdouble; | |
| 2909 | #endif | |
| 2068 | 2910 | typedef long double zig_f80; |
| 2069 | 2911 | #define zig_make_f80(fp, repr) fp##l |
| 2070 | 2912 | #elif FLT80_MANT_DIG == 64 |
| ... | ... | @@ -2084,14 +2926,15 @@ typedef zig_i128 zig_f80; |
| 2084 | 2926 | #define zig_make_f80(fp, repr) repr |
| 2085 | 2927 | #undef zig_make_special_f80 |
| 2086 | 2928 | #define zig_make_special_f80(sign, name, arg, repr) repr |
| 2087 | #undef zig_make_special_constant_f80 | |
| 2088 | #define zig_make_special_constant_f80(sign, name, arg, repr) repr | |
| 2929 | #undef zig_init_special_f80 | |
| 2930 | #define zig_init_special_f80(sign, name, arg, repr) repr | |
| 2089 | 2931 | #endif |
| 2090 | 2932 | |
| 2091 | 2933 | #define zig_has_f128 1 |
| 2092 | 2934 | #define zig_bitSizeOf_f128 128 |
| 2935 | typedef zig_i128 zig_repr_f128; | |
| 2093 | 2936 | #define zig_libc_name_f128(name) name##q |
| 2094 | #define zig_make_special_constant_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) | |
| 2937 | #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) | |
| 2095 | 2938 | #if FLT_MANT_DIG == 113 |
| 2096 | 2939 | typedef float zig_f128; |
| 2097 | 2940 | #define zig_make_f128(fp, repr) fp##f |
| ... | ... | @@ -2100,7 +2943,9 @@ typedef double zig_f128; |
| 2100 | 2943 | #define zig_make_f128(fp, repr) fp |
| 2101 | 2944 | #elif LDBL_MANT_DIG == 113 |
| 2102 | 2945 | #define zig_bitSizeOf_c_longdouble 128 |
| 2103 | typedef zig_u128 zig_repr_c_longdouble; | |
| 2946 | #ifndef ZIG_TARGET_ABI_MSVC | |
| 2947 | typedef zig_repr_f128 zig_repr_c_longdouble; | |
| 2948 | #endif | |
| 2104 | 2949 | typedef long double zig_f128; |
| 2105 | 2950 | #define zig_make_f128(fp, repr) fp##l |
| 2106 | 2951 | #elif FLT128_MANT_DIG == 113 |
| ... | ... | @@ -2122,63 +2967,44 @@ typedef zig_i128 zig_f128; |
| 2122 | 2967 | #define zig_make_f128(fp, repr) repr |
| 2123 | 2968 | #undef zig_make_special_f128 |
| 2124 | 2969 | #define zig_make_special_f128(sign, name, arg, repr) repr |
| 2125 | #undef zig_make_special_constant_f128 | |
| 2126 | #define zig_make_special_constant_f128(sign, name, arg, repr) repr | |
| 2970 | #undef zig_init_special_f128 | |
| 2971 | #define zig_init_special_f128(sign, name, arg, repr) repr | |
| 2127 | 2972 | #endif |
| 2128 | 2973 | |
| 2129 | #define zig_has_c_longdouble 1 | |
| 2130 | ||
| 2131 | #ifdef ZIG_TARGET_ABI_MSVC | |
| 2132 | #define zig_libc_name_c_longdouble(name) name | |
| 2133 | #else | |
| 2134 | #define zig_libc_name_c_longdouble(name) name##l | |
| 2135 | #endif | |
| 2136 | ||
| 2137 | #define zig_make_special_constant_c_longdouble(sign, name, arg, repr) zig_make_special_c_longdouble(sign, name, arg, repr) | |
| 2138 | 2974 | #ifdef zig_bitSizeOf_c_longdouble |
| 2139 | 2975 | |
| 2976 | #define zig_has_c_longdouble 1 | |
| 2140 | 2977 | #ifdef ZIG_TARGET_ABI_MSVC |
| 2141 | 2978 | #undef zig_bitSizeOf_c_longdouble |
| 2142 | 2979 | #define zig_bitSizeOf_c_longdouble 64 |
| 2143 | typedef uint64_t zig_repr_c_longdouble; | |
| 2144 | 2980 | typedef zig_f64 zig_c_longdouble; |
| 2145 | #define zig_make_c_longdouble(fp, repr) fp | |
| 2981 | typedef zig_repr_f64 zig_repr_c_longdouble; | |
| 2146 | 2982 | #else |
| 2147 | 2983 | typedef long double zig_c_longdouble; |
| 2148 | #define zig_make_c_longdouble(fp, repr) fp##l | |
| 2149 | 2984 | #endif |
| 2150 | 2985 | |
| 2151 | 2986 | #else /* zig_bitSizeOf_c_longdouble */ |
| 2152 | 2987 | |
| 2153 | #undef zig_has_c_longdouble | |
| 2154 | 2988 | #define zig_has_c_longdouble 0 |
| 2155 | #define zig_bitSizeOf_c_longdouble 80 | |
| 2156 | typedef zig_u128 zig_repr_c_longdouble; | |
| 2157 | #define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f80 | |
| 2158 | 2989 | #define zig_bitSizeOf_repr_c_longdouble 128 |
| 2159 | typedef zig_i128 zig_c_longdouble; | |
| 2160 | #define zig_make_c_longdouble(fp, repr) repr | |
| 2161 | #undef zig_make_special_c_longdouble | |
| 2162 | #define zig_make_special_c_longdouble(sign, name, arg, repr) repr | |
| 2163 | #undef zig_make_special_constant_c_longdouble | |
| 2164 | #define zig_make_special_constant_c_longdouble(sign, name, arg, repr) repr | |
| 2990 | typedef zig_f128 zig_c_longdouble; | |
| 2991 | typedef zig_repr_f128 zig_repr_c_longdouble; | |
| 2165 | 2992 | |
| 2166 | 2993 | #endif /* zig_bitSizeOf_c_longdouble */ |
| 2167 | 2994 | |
| 2168 | 2995 | #if !zig_has_float_builtins |
| 2169 | #define zig_float_from_repr(Type, ReprType) \ | |
| 2170 | static inline zig_##Type zig_float_from_repr_##Type(ReprType repr) { \ | |
| 2996 | #define zig_float_from_repr(Type) \ | |
| 2997 | static inline zig_##Type zig_float_from_repr_##Type(zig_repr_##Type repr) { \ | |
| 2171 | 2998 | zig_##Type result; \ |
| 2172 | 2999 | memcpy(&result, &repr, sizeof(result)); \ |
| 2173 | 3000 | return result; \ |
| 2174 | 3001 | } |
| 2175 | 3002 | |
| 2176 | zig_float_from_repr(f16, uint16_t) | |
| 2177 | zig_float_from_repr(f32, uint32_t) | |
| 2178 | zig_float_from_repr(f64, uint64_t) | |
| 2179 | zig_float_from_repr(f80, zig_u128) | |
| 2180 | zig_float_from_repr(f128, zig_u128) | |
| 2181 | zig_float_from_repr(c_longdouble, zig_repr_c_longdouble) | |
| 3003 | zig_float_from_repr(f16) | |
| 3004 | zig_float_from_repr(f32) | |
| 3005 | zig_float_from_repr(f64) | |
| 3006 | zig_float_from_repr(f80) | |
| 3007 | zig_float_from_repr(f128) | |
| 2182 | 3008 | #endif |
| 2183 | 3009 | |
| 2184 | 3010 | #define zig_cast_f16 (zig_f16) |
| ... | ... | @@ -2187,11 +3013,9 @@ zig_float_from_repr(c_longdouble, zig_repr_c_longdouble) |
| 2187 | 3013 | |
| 2188 | 3014 | #if _MSC_VER && !zig_has_f128 |
| 2189 | 3015 | #define zig_cast_f80 |
| 2190 | #define zig_cast_c_longdouble | |
| 2191 | 3016 | #define zig_cast_f128 |
| 2192 | 3017 | #else |
| 2193 | 3018 | #define zig_cast_f80 (zig_f80) |
| 2194 | #define zig_cast_c_longdouble (zig_c_longdouble) | |
| 2195 | 3019 | #define zig_cast_f128 (zig_f128) |
| 2196 | 3020 | #endif |
| 2197 | 3021 | |
| ... | ... | @@ -2320,7 +3144,6 @@ zig_float_builtins(f32) |
| 2320 | 3144 | zig_float_builtins(f64) |
| 2321 | 3145 | zig_float_builtins(f80) |
| 2322 | 3146 | zig_float_builtins(f128) |
| 2323 | zig_float_builtins(c_longdouble) | |
| 2324 | 3147 | |
| 2325 | 3148 | #if _MSC_VER && (_M_IX86 || _M_X64) |
| 2326 | 3149 |
src/Sema.zig+19-21| ... | ... | @@ -574,11 +574,13 @@ pub const Block = struct { |
| 574 | 574 | }); |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator, vector_ty: Air.Inst.Ref) !Air.Inst.Ref { | |
| 577 | fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref { | |
| 578 | 578 | return block.addInst(.{ |
| 579 | 579 | .tag = if (block.float_mode == .Optimized) .cmp_vector_optimized else .cmp_vector, |
| 580 | 580 | .data = .{ .ty_pl = .{ |
| 581 | .ty = vector_ty, | |
| 581 | .ty = try block.sema.addType( | |
| 582 | try Type.vector(block.sema.arena, block.sema.typeOf(lhs).vectorLen(), Type.bool), | |
| 583 | ), | |
| 582 | 584 | .payload = try block.sema.addExtra(Air.VectorCmp{ |
| 583 | 585 | .lhs = lhs, |
| 584 | 586 | .rhs = rhs, |
| ... | ... | @@ -9412,7 +9414,7 @@ fn intCast( |
| 9412 | 9414 | const ok = if (is_vector) ok: { |
| 9413 | 9415 | const zeros = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 9414 | 9416 | const zero_inst = try sema.addConstant(sema.typeOf(operand), zeros); |
| 9415 | const is_in_range = try block.addCmpVector(operand, zero_inst, .eq, try sema.addType(operand_ty)); | |
| 9417 | const is_in_range = try block.addCmpVector(operand, zero_inst, .eq); | |
| 9416 | 9418 | const all_in_range = try block.addInst(.{ |
| 9417 | 9419 | .tag = .reduce, |
| 9418 | 9420 | .data = .{ .reduce = .{ .operand = is_in_range, .operation = .And } }, |
| ... | ... | @@ -9466,7 +9468,7 @@ fn intCast( |
| 9466 | 9468 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); |
| 9467 | 9469 | |
| 9468 | 9470 | const ok = if (is_vector) ok: { |
| 9469 | const is_in_range = try block.addCmpVector(diff_unsigned, dest_range, .lte, try sema.addType(operand_ty)); | |
| 9471 | const is_in_range = try block.addCmpVector(diff_unsigned, dest_range, .lte); | |
| 9470 | 9472 | const all_in_range = try block.addInst(.{ |
| 9471 | 9473 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, |
| 9472 | 9474 | .data = .{ .reduce = .{ |
| ... | ... | @@ -9483,7 +9485,7 @@ fn intCast( |
| 9483 | 9485 | try sema.addSafetyCheck(block, ok, .cast_truncated_data); |
| 9484 | 9486 | } else { |
| 9485 | 9487 | const ok = if (is_vector) ok: { |
| 9486 | const is_in_range = try block.addCmpVector(diff, dest_max, .lte, try sema.addType(operand_ty)); | |
| 9488 | const is_in_range = try block.addCmpVector(diff, dest_max, .lte); | |
| 9487 | 9489 | const all_in_range = try block.addInst(.{ |
| 9488 | 9490 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, |
| 9489 | 9491 | .data = .{ .reduce = .{ |
| ... | ... | @@ -9504,7 +9506,7 @@ fn intCast( |
| 9504 | 9506 | const ok = if (is_vector) ok: { |
| 9505 | 9507 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 9506 | 9508 | const zero_inst = try sema.addConstant(operand_ty, zero_val); |
| 9507 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte, try sema.addType(operand_ty)); | |
| 9509 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte); | |
| 9508 | 9510 | const all_in_range = try block.addInst(.{ |
| 9509 | 9511 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, |
| 9510 | 9512 | .data = .{ .reduce = .{ |
| ... | ... | @@ -12016,7 +12018,7 @@ fn zirShl( |
| 12016 | 12018 | |
| 12017 | 12019 | const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: { |
| 12018 | 12020 | const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val)); |
| 12019 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt, try sema.addType(rhs_ty)); | |
| 12021 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); | |
| 12020 | 12022 | break :ok try block.addInst(.{ |
| 12021 | 12023 | .tag = .reduce, |
| 12022 | 12024 | .data = .{ .reduce = .{ |
| ... | ... | @@ -12172,7 +12174,7 @@ fn zirShr( |
| 12172 | 12174 | |
| 12173 | 12175 | const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: { |
| 12174 | 12176 | const bit_count_inst = try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, bit_count_val)); |
| 12175 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt, try sema.addType(rhs_ty)); | |
| 12177 | const lt = try block.addCmpVector(rhs, bit_count_inst, .lt); | |
| 12176 | 12178 | break :ok try block.addInst(.{ |
| 12177 | 12179 | .tag = .reduce, |
| 12178 | 12180 | .data = .{ .reduce = .{ |
| ... | ... | @@ -12191,7 +12193,7 @@ fn zirShr( |
| 12191 | 12193 | const back = try block.addBinOp(.shl, result, rhs); |
| 12192 | 12194 | |
| 12193 | 12195 | const ok = if (rhs_ty.zigTypeTag() == .Vector) ok: { |
| 12194 | const eql = try block.addCmpVector(lhs, back, .eq, try sema.addType(rhs_ty)); | |
| 12196 | const eql = try block.addCmpVector(lhs, back, .eq); | |
| 12195 | 12197 | break :ok try block.addInst(.{ |
| 12196 | 12198 | .tag = if (block.float_mode == .Optimized) .reduce_optimized else .reduce, |
| 12197 | 12199 | .data = .{ .reduce = .{ |
| ... | ... | @@ -13192,7 +13194,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13192 | 13194 | const floored = try block.addUnOp(.floor, result); |
| 13193 | 13195 | |
| 13194 | 13196 | if (resolved_type.zigTypeTag() == .Vector) { |
| 13195 | const eql = try block.addCmpVector(result, floored, .eq, try sema.addType(resolved_type)); | |
| 13197 | const eql = try block.addCmpVector(result, floored, .eq); | |
| 13196 | 13198 | break :ok try block.addInst(.{ |
| 13197 | 13199 | .tag = switch (block.float_mode) { |
| 13198 | 13200 | .Strict => .reduce, |
| ... | ... | @@ -13216,7 +13218,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13216 | 13218 | if (resolved_type.zigTypeTag() == .Vector) { |
| 13217 | 13219 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 13218 | 13220 | const zero = try sema.addConstant(resolved_type, zero_val); |
| 13219 | const eql = try block.addCmpVector(remainder, zero, .eq, try sema.addType(resolved_type)); | |
| 13221 | const eql = try block.addCmpVector(remainder, zero, .eq); | |
| 13220 | 13222 | break :ok try block.addInst(.{ |
| 13221 | 13223 | .tag = .reduce, |
| 13222 | 13224 | .data = .{ .reduce = .{ |
| ... | ... | @@ -13514,14 +13516,13 @@ fn addDivIntOverflowSafety( |
| 13514 | 13516 | |
| 13515 | 13517 | var ok: Air.Inst.Ref = .none; |
| 13516 | 13518 | if (resolved_type.zigTypeTag() == .Vector) { |
| 13517 | const vector_ty_ref = try sema.addType(resolved_type); | |
| 13518 | 13519 | if (maybe_lhs_val == null) { |
| 13519 | 13520 | const min_int_ref = try sema.addConstant(resolved_type, min_int); |
| 13520 | ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq, vector_ty_ref); | |
| 13521 | ok = try block.addCmpVector(casted_lhs, min_int_ref, .neq); | |
| 13521 | 13522 | } |
| 13522 | 13523 | if (maybe_rhs_val == null) { |
| 13523 | 13524 | const neg_one_ref = try sema.addConstant(resolved_type, neg_one); |
| 13524 | const rhs_ok = try block.addCmpVector(casted_rhs, neg_one_ref, .neq, vector_ty_ref); | |
| 13525 | const rhs_ok = try block.addCmpVector(casted_rhs, neg_one_ref, .neq); | |
| 13525 | 13526 | if (ok == .none) { |
| 13526 | 13527 | ok = rhs_ok; |
| 13527 | 13528 | } else { |
| ... | ... | @@ -13573,7 +13574,7 @@ fn addDivByZeroSafety( |
| 13573 | 13574 | const ok = if (resolved_type.zigTypeTag() == .Vector) ok: { |
| 13574 | 13575 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); |
| 13575 | 13576 | const zero = try sema.addConstant(resolved_type, zero_val); |
| 13576 | const ok = try block.addCmpVector(casted_rhs, zero, .neq, try sema.addType(resolved_type)); | |
| 13577 | const ok = try block.addCmpVector(casted_rhs, zero, .neq); | |
| 13577 | 13578 | break :ok try block.addInst(.{ |
| 13578 | 13579 | .tag = if (is_int) .reduce else .reduce_optimized, |
| 13579 | 13580 | .data = .{ .reduce = .{ |
| ... | ... | @@ -15202,9 +15203,7 @@ fn cmpSelf( |
| 15202 | 15203 | }; |
| 15203 | 15204 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 15204 | 15205 | if (resolved_type.zigTypeTag() == .Vector) { |
| 15205 | const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.bool); | |
| 15206 | const result_ty_ref = try sema.addType(result_ty); | |
| 15207 | return block.addCmpVector(casted_lhs, casted_rhs, op, result_ty_ref); | |
| 15206 | return block.addCmpVector(casted_lhs, casted_rhs, op); | |
| 15208 | 15207 | } |
| 15209 | 15208 | const tag = Air.Inst.Tag.fromCmpOp(op, block.float_mode == .Optimized); |
| 15210 | 15209 | return block.addBinOp(tag, casted_lhs, casted_rhs); |
| ... | ... | @@ -23035,7 +23034,7 @@ fn panicSentinelMismatch( |
| 23035 | 23034 | |
| 23036 | 23035 | const ok = if (sentinel_ty.zigTypeTag() == .Vector) ok: { |
| 23037 | 23036 | const eql = |
| 23038 | try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq, try sema.addType(sentinel_ty)); | |
| 23037 | try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq); | |
| 23039 | 23038 | break :ok try parent_block.addInst(.{ |
| 23040 | 23039 | .tag = .reduce, |
| 23041 | 23040 | .data = .{ .reduce = .{ |
| ... | ... | @@ -29368,8 +29367,7 @@ fn cmpVector( |
| 29368 | 29367 | }; |
| 29369 | 29368 | |
| 29370 | 29369 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 29371 | const result_ty_inst = try sema.addType(result_ty); | |
| 29372 | return block.addCmpVector(lhs, rhs, op, result_ty_inst); | |
| 29370 | return block.addCmpVector(lhs, rhs, op); | |
| 29373 | 29371 | } |
| 29374 | 29372 | |
| 29375 | 29373 | fn wrapOptional( |
src/codegen/c.zig+895-511| ... | ... | @@ -17,12 +17,6 @@ const LazySrcLoc = Module.LazySrcLoc; |
| 17 | 17 | const Air = @import("../Air.zig"); |
| 18 | 18 | const Liveness = @import("../Liveness.zig"); |
| 19 | 19 | |
| 20 | const target_util = @import("../target.zig"); | |
| 21 | const libcFloatPrefix = target_util.libcFloatPrefix; | |
| 22 | const libcFloatSuffix = target_util.libcFloatSuffix; | |
| 23 | const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev; | |
| 24 | const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; | |
| 25 | ||
| 26 | 20 | const BigIntLimb = std.math.big.Limb; |
| 27 | 21 | const BigInt = std.math.big.int; |
| 28 | 22 | |
| ... | ... | @@ -112,11 +106,7 @@ const ValueRenderLocation = enum { |
| 112 | 106 | } |
| 113 | 107 | }; |
| 114 | 108 | |
| 115 | const BuiltinInfo = enum { | |
| 116 | None, | |
| 117 | Range, | |
| 118 | Bits, | |
| 119 | }; | |
| 109 | const BuiltinInfo = enum { none, bits }; | |
| 120 | 110 | |
| 121 | 111 | const reserved_idents = std.ComptimeStringMap(void, .{ |
| 122 | 112 | // C language |
| ... | ... | @@ -440,16 +430,24 @@ pub const Function = struct { |
| 440 | 430 | return f.object.dg.typeToCType(ty, kind); |
| 441 | 431 | } |
| 442 | 432 | |
| 433 | fn byteSize(f: *Function, cty: CType) u64 { | |
| 434 | return f.object.dg.byteSize(cty); | |
| 435 | } | |
| 436 | ||
| 443 | 437 | fn renderType(f: *Function, w: anytype, t: Type) !void { |
| 444 | 438 | return f.object.dg.renderType(w, t); |
| 445 | 439 | } |
| 446 | 440 | |
| 447 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, src_ty: Type, location: ValueRenderLocation) !void { | |
| 448 | return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src } }, src_ty, location); | |
| 441 | fn renderCType(f: *Function, w: anytype, t: CType.Index) !void { | |
| 442 | return f.object.dg.renderCType(w, t); | |
| 443 | } | |
| 444 | ||
| 445 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void { | |
| 446 | return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); | |
| 449 | 447 | } |
| 450 | 448 | |
| 451 | 449 | fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) { |
| 452 | return f.object.dg.fmtIntLiteral(ty, val); | |
| 450 | return f.object.dg.fmtIntLiteral(ty, val, .Other); | |
| 453 | 451 | } |
| 454 | 452 | |
| 455 | 453 | fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 { |
| ... | ... | @@ -574,9 +572,9 @@ pub const DeclGen = struct { |
| 574 | 572 | const len_val = Value.initPayload(&len_pl.base); |
| 575 | 573 | |
| 576 | 574 | if (location == .StaticInitializer) { |
| 577 | return writer.print(", {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)}); | |
| 575 | return writer.print(", {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val, .Other)}); | |
| 578 | 576 | } else { |
| 579 | return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)}); | |
| 577 | return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val, .Other)}); | |
| 580 | 578 | } |
| 581 | 579 | } |
| 582 | 580 | |
| ... | ... | @@ -606,7 +604,7 @@ pub const DeclGen = struct { |
| 606 | 604 | try writer.writeByte(')'); |
| 607 | 605 | } |
| 608 | 606 | switch (ptr_val.tag()) { |
| 609 | .int_u64, .one => try writer.print("{x}", .{try dg.fmtIntLiteral(Type.usize, ptr_val)}), | |
| 607 | .int_u64, .one => try writer.print("{x}", .{try dg.fmtIntLiteral(Type.usize, ptr_val, .Other)}), | |
| 610 | 608 | .decl_ref_mut, .decl_ref, .variable => { |
| 611 | 609 | const decl_index = switch (ptr_val.tag()) { |
| 612 | 610 | .decl_ref => ptr_val.castTag(.decl_ref).?.data, |
| ... | ... | @@ -670,7 +668,9 @@ pub const DeclGen = struct { |
| 670 | 668 | container_ptr_ty, |
| 671 | 669 | location, |
| 672 | 670 | ); |
| 673 | try writer.print(" + {})", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)}); | |
| 671 | try writer.print(" + {})", .{ | |
| 672 | try dg.fmtIntLiteral(Type.usize, byte_offset_val, .Other), | |
| 673 | }); | |
| 674 | 674 | }, |
| 675 | 675 | .end => { |
| 676 | 676 | try writer.writeAll("(("); |
| ... | ... | @@ -680,7 +680,9 @@ pub const DeclGen = struct { |
| 680 | 680 | container_ptr_ty, |
| 681 | 681 | location, |
| 682 | 682 | ); |
| 683 | try writer.print(") + {})", .{try dg.fmtIntLiteral(Type.usize, Value.one)}); | |
| 683 | try writer.print(") + {})", .{ | |
| 684 | try dg.fmtIntLiteral(Type.usize, Value.one, .Other), | |
| 685 | }); | |
| 684 | 686 | }, |
| 685 | 687 | } |
| 686 | 688 | }, |
| ... | ... | @@ -746,7 +748,7 @@ pub const DeclGen = struct { |
| 746 | 748 | return writer.writeAll("false"); |
| 747 | 749 | } |
| 748 | 750 | }, |
| 749 | .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteralLoc(ty, val, location)}), | |
| 751 | .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}), | |
| 750 | 752 | .Float => { |
| 751 | 753 | const bits = ty.floatBits(target); |
| 752 | 754 | var int_pl = Type.Payload.Bits{ .base = .{ .tag = .int_signed }, .data = bits }; |
| ... | ... | @@ -780,11 +782,11 @@ pub const DeclGen = struct { |
| 780 | 782 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 781 | 783 | const ptr_ty = ty.slicePtrFieldType(&buf); |
| 782 | 784 | try dg.renderType(writer, ptr_ty); |
| 783 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)}); | |
| 785 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); | |
| 784 | 786 | } else { |
| 785 | 787 | try writer.writeAll("(("); |
| 786 | 788 | try dg.renderType(writer, ty); |
| 787 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); | |
| 789 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); | |
| 788 | 790 | }, |
| 789 | 791 | .Optional => { |
| 790 | 792 | var opt_buf: Type.Payload.ElemType = undefined; |
| ... | ... | @@ -831,7 +833,7 @@ pub const DeclGen = struct { |
| 831 | 833 | |
| 832 | 834 | return writer.writeByte('}'); |
| 833 | 835 | }, |
| 834 | .Packed => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, Value.undef)}), | |
| 836 | .Packed => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, Value.undef, .Other)}), | |
| 835 | 837 | }, |
| 836 | 838 | .Union => { |
| 837 | 839 | if (!location.isInitializer()) { |
| ... | ... | @@ -854,7 +856,7 @@ pub const DeclGen = struct { |
| 854 | 856 | if (!field.ty.hasRuntimeBits()) continue; |
| 855 | 857 | try dg.renderValue(writer, field.ty, val, initializer_type); |
| 856 | 858 | break; |
| 857 | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)}); | |
| 859 | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef, .Other)}); | |
| 858 | 860 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 859 | 861 | return writer.writeByte('}'); |
| 860 | 862 | }, |
| ... | ... | @@ -868,7 +870,7 @@ pub const DeclGen = struct { |
| 868 | 870 | try writer.writeAll("{ .payload = "); |
| 869 | 871 | try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type); |
| 870 | 872 | return writer.print(", .error = {x} }}", .{ |
| 871 | try dg.fmtIntLiteral(ty.errorUnionSet(), val), | |
| 873 | try dg.fmtIntLiteral(ty.errorUnionSet(), val, .Other), | |
| 872 | 874 | }); |
| 873 | 875 | }, |
| 874 | 876 | .Array, .Vector => { |
| ... | ... | @@ -927,7 +929,7 @@ pub const DeclGen = struct { |
| 927 | 929 | .decl_ref_mut, |
| 928 | 930 | .decl_ref, |
| 929 | 931 | => try dg.renderParentPtr(writer, val, ty, location), |
| 930 | else => try writer.print("{}", .{try dg.fmtIntLiteralLoc(ty, val, location)}), | |
| 932 | else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, location)}), | |
| 931 | 933 | }, |
| 932 | 934 | .Float => { |
| 933 | 935 | const bits = ty.floatBits(target); |
| ... | ... | @@ -999,8 +1001,9 @@ pub const DeclGen = struct { |
| 999 | 1001 | // return dg.fail("Only quiet nans are supported in global variable initializers", .{}); |
| 1000 | 1002 | } |
| 1001 | 1003 | |
| 1002 | try writer.writeAll("zig_make_special_"); | |
| 1003 | if (location == .StaticInitializer) try writer.writeAll("constant_"); | |
| 1004 | try writer.writeAll("zig_"); | |
| 1005 | try writer.writeAll(if (location == .StaticInitializer) "init" else "make"); | |
| 1006 | try writer.writeAll("_special_"); | |
| 1004 | 1007 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 1005 | 1008 | try writer.writeByte('('); |
| 1006 | 1009 | if (std.math.signbit(f128_val)) try writer.writeByte('-'); |
| ... | ... | @@ -1020,7 +1023,7 @@ pub const DeclGen = struct { |
| 1020 | 1023 | try writer.writeAll(", "); |
| 1021 | 1024 | empty = false; |
| 1022 | 1025 | } |
| 1023 | try writer.print("{x}", .{try dg.fmtIntLiteralLoc(int_ty, int_val, location)}); | |
| 1026 | try writer.print("{x}", .{try dg.fmtIntLiteral(int_ty, int_val, location)}); | |
| 1024 | 1027 | if (!empty) try writer.writeByte(')'); |
| 1025 | 1028 | return; |
| 1026 | 1029 | }, |
| ... | ... | @@ -1069,7 +1072,7 @@ pub const DeclGen = struct { |
| 1069 | 1072 | .int_u64, .one => { |
| 1070 | 1073 | try writer.writeAll("(("); |
| 1071 | 1074 | try dg.renderType(writer, ty); |
| 1072 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); | |
| 1075 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); | |
| 1073 | 1076 | }, |
| 1074 | 1077 | .field_ptr, |
| 1075 | 1078 | .elem_ptr, |
| ... | ... | @@ -1561,6 +1564,10 @@ pub const DeclGen = struct { |
| 1561 | 1564 | return dg.ctypes.typeToCType(dg.gpa, ty, dg.module, kind); |
| 1562 | 1565 | } |
| 1563 | 1566 | |
| 1567 | fn byteSize(dg: *DeclGen, cty: CType) u64 { | |
| 1568 | return cty.byteSize(dg.ctypes.set, dg.module.getTarget()); | |
| 1569 | } | |
| 1570 | ||
| 1564 | 1571 | /// Renders a type as a single identifier, generating intermediate typedefs |
| 1565 | 1572 | /// if necessary. |
| 1566 | 1573 | /// |
| ... | ... | @@ -1573,9 +1580,12 @@ pub const DeclGen = struct { |
| 1573 | 1580 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | |
| 1574 | 1581 | /// |
| 1575 | 1582 | fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void { |
| 1583 | try dg.renderCType(w, try dg.typeToIndex(t, .complete)); | |
| 1584 | } | |
| 1585 | ||
| 1586 | fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void { | |
| 1576 | 1587 | const store = &dg.ctypes.set; |
| 1577 | 1588 | const module = dg.module; |
| 1578 | const idx = try dg.typeToIndex(t, .complete); | |
| 1579 | 1589 | _ = try renderTypePrefix(dg.decl_index, store.*, module, w, idx, .suffix, .{}); |
| 1580 | 1590 | try renderTypeSuffix(dg.decl_index, store.*, module, w, idx, .suffix, .{}); |
| 1581 | 1591 | } |
| ... | ... | @@ -1584,6 +1594,7 @@ pub const DeclGen = struct { |
| 1584 | 1594 | c_value: struct { |
| 1585 | 1595 | f: *Function, |
| 1586 | 1596 | value: CValue, |
| 1597 | v: Vectorizer, | |
| 1587 | 1598 | }, |
| 1588 | 1599 | value: struct { |
| 1589 | 1600 | value: Value, |
| ... | ... | @@ -1593,6 +1604,7 @@ pub const DeclGen = struct { |
| 1593 | 1604 | switch (self.*) { |
| 1594 | 1605 | .c_value => |v| { |
| 1595 | 1606 | try v.f.writeCValue(w, v.value, location); |
| 1607 | try v.v.elem(v.f, w); | |
| 1596 | 1608 | }, |
| 1597 | 1609 | .value => |v| { |
| 1598 | 1610 | try dg.renderValue(w, value_ty, v.value, location); |
| ... | ... | @@ -1829,79 +1841,67 @@ pub const DeclGen = struct { |
| 1829 | 1841 | dg.module.markDeclAlive(decl); |
| 1830 | 1842 | |
| 1831 | 1843 | if (dg.module.decl_exports.get(decl_index)) |exports| { |
| 1832 | return writer.writeAll(exports.items[export_index].options.name); | |
| 1844 | try writer.writeAll(exports.items[export_index].options.name); | |
| 1833 | 1845 | } else if (decl.isExtern()) { |
| 1834 | return writer.writeAll(mem.sliceTo(decl.name, 0)); | |
| 1835 | } else if (dg.module.test_functions.get(decl_index)) |_| { | |
| 1836 | const gpa = dg.gpa; | |
| 1837 | const name = try decl.getFullyQualifiedName(dg.module); | |
| 1838 | defer gpa.free(name); | |
| 1839 | return writer.print("{}_{d}", .{ fmtIdent(name), @enumToInt(decl_index) }); | |
| 1846 | try writer.writeAll(mem.sliceTo(decl.name, 0)); | |
| 1840 | 1847 | } else { |
| 1841 | const gpa = dg.gpa; | |
| 1842 | const name = try decl.getFullyQualifiedName(dg.module); | |
| 1843 | defer gpa.free(name); | |
| 1844 | ||
| 1845 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), expand | |
| 1846 | // to 3x the length of its input | |
| 1847 | if (name.len > 1365) { | |
| 1848 | var hash = ident_hasher_init; | |
| 1849 | hash.update(name); | |
| 1850 | const ident_hash = hash.finalInt(); | |
| 1851 | try writer.writeAll("zig_D_"); | |
| 1852 | return std.fmt.formatIntValue(ident_hash, "x", .{}, writer); | |
| 1853 | } else { | |
| 1854 | return writer.print("{}", .{fmtIdent(name)}); | |
| 1855 | } | |
| 1848 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), | |
| 1849 | // expand to 3x the length of its input, but let's cut it off at a much shorter limit. | |
| 1850 | var name: [100]u8 = undefined; | |
| 1851 | var name_stream = std.io.fixedBufferStream(&name); | |
| 1852 | decl.renderFullyQualifiedName(dg.module, name_stream.writer()) catch |err| switch (err) { | |
| 1853 | error.NoSpaceLeft => {}, | |
| 1854 | }; | |
| 1855 | try writer.print("{}__{d}", .{ | |
| 1856 | fmtIdent(name_stream.getWritten()), | |
| 1857 | @enumToInt(decl_index), | |
| 1858 | }); | |
| 1856 | 1859 | } |
| 1857 | 1860 | } |
| 1858 | 1861 | |
| 1859 | 1862 | fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void { |
| 1860 | const target = dg.module.getTarget(); | |
| 1861 | if (ty.isAbiInt()) { | |
| 1862 | const int_info = ty.intInfo(target); | |
| 1863 | const c_bits = toCIntBits(int_info.bits) orelse | |
| 1864 | return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | |
| 1865 | try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits }); | |
| 1866 | } else if (ty.isRuntimeFloat()) { | |
| 1867 | try ty.print(writer, dg.module); | |
| 1868 | } else if (ty.isPtrAtRuntime()) { | |
| 1869 | try writer.print("p{d}", .{ty.bitSize(target)}); | |
| 1870 | } else if (ty.zigTypeTag() == .Bool) { | |
| 1871 | try writer.print("u8", .{}); | |
| 1872 | } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{ | |
| 1873 | ty.fmt(dg.module), | |
| 1874 | }); | |
| 1863 | try dg.renderCTypeForBuiltinFnName(writer, try dg.typeToCType(ty, .complete)); | |
| 1864 | } | |
| 1865 | ||
| 1866 | fn renderCTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, cty: CType) !void { | |
| 1867 | switch (cty.tag()) { | |
| 1868 | else => try writer.print("{c}{d}", .{ | |
| 1869 | if (cty.isBool()) | |
| 1870 | signAbbrev(.unsigned) | |
| 1871 | else if (cty.isInteger()) | |
| 1872 | signAbbrev(cty.signedness() orelse .unsigned) | |
| 1873 | else if (cty.isFloat()) | |
| 1874 | @as(u8, 'f') | |
| 1875 | else if (cty.isPointer()) | |
| 1876 | @as(u8, 'p') | |
| 1877 | else | |
| 1878 | return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{ | |
| 1879 | cty.tag(), | |
| 1880 | }), | |
| 1881 | if (cty.isFloat()) cty.floatActiveBits(dg.module.getTarget()) else dg.byteSize(cty) * 8, | |
| 1882 | }), | |
| 1883 | .array => try writer.writeAll("big"), | |
| 1884 | } | |
| 1875 | 1885 | } |
| 1876 | 1886 | |
| 1877 | 1887 | fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void { |
| 1878 | const target = dg.module.getTarget(); | |
| 1879 | 1888 | switch (info) { |
| 1880 | .None => {}, | |
| 1881 | .Range => { | |
| 1882 | var arena = std.heap.ArenaAllocator.init(dg.gpa); | |
| 1883 | defer arena.deinit(); | |
| 1884 | ||
| 1885 | const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 }; | |
| 1886 | var stack align(@alignOf(ExpectedContents)) = | |
| 1887 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | |
| 1888 | ||
| 1889 | const int_info = ty.intInfo(target); | |
| 1890 | if (int_info.signedness == .signed) { | |
| 1891 | const min_val = try ty.minInt(stack.get(), target); | |
| 1892 | try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, min_val)}); | |
| 1893 | } | |
| 1894 | ||
| 1895 | const max_val = try ty.maxInt(stack.get(), target); | |
| 1896 | try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, max_val)}); | |
| 1897 | }, | |
| 1898 | .Bits => { | |
| 1899 | var bits_pl = Value.Payload.U64{ | |
| 1900 | .base = .{ .tag = .int_u64 }, | |
| 1901 | .data = ty.bitSize(target), | |
| 1889 | .none => {}, | |
| 1890 | .bits => { | |
| 1891 | const target = dg.module.getTarget(); | |
| 1892 | const int_info = if (ty.isAbiInt()) ty.intInfo(target) else std.builtin.Type.Int{ | |
| 1893 | .signedness = .unsigned, | |
| 1894 | .bits = @intCast(u16, ty.bitSize(target)), | |
| 1902 | 1895 | }; |
| 1903 | const bits_val = Value.initPayload(&bits_pl.base); | |
| 1904 | try writer.print(", {}", .{try dg.fmtIntLiteral(Type.u8, bits_val)}); | |
| 1896 | ||
| 1897 | const cty = try dg.typeToCType(ty, .complete); | |
| 1898 | if (cty.tag() == .array) try writer.print(", {}", .{int_info.signedness == .signed}); | |
| 1899 | ||
| 1900 | var bits_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = int_info.bits }; | |
| 1901 | try writer.print(", {}", .{try dg.fmtIntLiteral(switch (cty.tag()) { | |
| 1902 | else => Type.u8, | |
| 1903 | .array => Type.u16, | |
| 1904 | }, Value.initPayload(&bits_pl.base), .FunctionArgument)}); | |
| 1905 | 1905 | }, |
| 1906 | 1906 | } |
| 1907 | 1907 | } |
| ... | ... | @@ -1910,30 +1910,21 @@ pub const DeclGen = struct { |
| 1910 | 1910 | dg: *DeclGen, |
| 1911 | 1911 | ty: Type, |
| 1912 | 1912 | val: Value, |
| 1913 | loc: ValueRenderLocation, | |
| 1913 | 1914 | ) !std.fmt.Formatter(formatIntLiteral) { |
| 1914 | const int_info = ty.intInfo(dg.module.getTarget()); | |
| 1915 | const c_bits = toCIntBits(int_info.bits); | |
| 1916 | if (c_bits == null or c_bits.? > 128) | |
| 1917 | return dg.fail("TODO implement integer constants larger than 128 bits", .{}); | |
| 1915 | const kind: CType.Kind = switch (loc) { | |
| 1916 | .FunctionArgument => .parameter, | |
| 1917 | .Initializer, .Other => .complete, | |
| 1918 | .StaticInitializer => .global, | |
| 1919 | }; | |
| 1918 | 1920 | return std.fmt.Formatter(formatIntLiteral){ .data = .{ |
| 1919 | .ty = ty, | |
| 1921 | .dg = dg, | |
| 1922 | .int_info = ty.intInfo(dg.module.getTarget()), | |
| 1923 | .kind = kind, | |
| 1924 | .cty = try dg.typeToCType(ty, kind), | |
| 1920 | 1925 | .val = val, |
| 1921 | .mod = dg.module, | |
| 1922 | 1926 | } }; |
| 1923 | 1927 | } |
| 1924 | ||
| 1925 | fn fmtIntLiteralLoc( | |
| 1926 | dg: *DeclGen, | |
| 1927 | ty: Type, | |
| 1928 | val: Value, | |
| 1929 | location: ValueRenderLocation, // TODO: Instead add this as optional arg to fmtIntLiteral | |
| 1930 | ) !std.fmt.Formatter(formatIntLiteral) { | |
| 1931 | const int_info = ty.intInfo(dg.module.getTarget()); | |
| 1932 | const c_bits = toCIntBits(int_info.bits); | |
| 1933 | if (c_bits == null or c_bits.? > 128) | |
| 1934 | return dg.fail("TODO implement integer constants larger than 128 bits", .{}); | |
| 1935 | return std.fmt.Formatter(formatIntLiteral){ .data = .{ .ty = ty, .val = val, .mod = dg.module, .location = location } }; | |
| 1936 | } | |
| 1937 | 1928 | }; |
| 1938 | 1929 | |
| 1939 | 1930 | const CTypeFix = enum { prefix, suffix }; |
| ... | ... | @@ -2450,7 +2441,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2450 | 2441 | const len_val = Value.initPayload(&len_pl.base); |
| 2451 | 2442 | |
| 2452 | 2443 | try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{ |
| 2453 | fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val), | |
| 2444 | fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other), | |
| 2454 | 2445 | }); |
| 2455 | 2446 | } |
| 2456 | 2447 | try writer.writeAll("};\n"); |
| ... | ... | @@ -2501,7 +2492,10 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2501 | 2492 | var int_pl: Value.Payload.U64 = undefined; |
| 2502 | 2493 | const int_val = tag_val.enumToInt(enum_ty, &int_pl); |
| 2503 | 2494 | |
| 2504 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; | |
| 2495 | var name_ty_pl = Type.Payload.Len{ | |
| 2496 | .base = .{ .tag = .array_u8_sentinel_0 }, | |
| 2497 | .data = name.len, | |
| 2498 | }; | |
| 2505 | 2499 | const name_ty = Type.initPayload(&name_ty_pl.base); |
| 2506 | 2500 | |
| 2507 | 2501 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name }; |
| ... | ... | @@ -2510,14 +2504,16 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2510 | 2504 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| 2511 | 2505 | const len_val = Value.initPayload(&len_pl.base); |
| 2512 | 2506 | |
| 2513 | try w.print(" case {}: {{\n static ", .{try o.dg.fmtIntLiteral(enum_ty, int_val)}); | |
| 2507 | try w.print(" case {}: {{\n static ", .{ | |
| 2508 | try o.dg.fmtIntLiteral(enum_ty, int_val, .Other), | |
| 2509 | }); | |
| 2514 | 2510 | try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, 0, .complete); |
| 2515 | 2511 | try w.writeAll(" = "); |
| 2516 | 2512 | try o.dg.renderValue(w, name_ty, name_val, .Initializer); |
| 2517 | 2513 | try w.writeAll(";\n return ("); |
| 2518 | 2514 | try o.dg.renderType(w, name_slice_ty); |
| 2519 | 2515 | try w.print("){{{}, {}}};\n", .{ |
| 2520 | fmtIdent("name"), try o.dg.fmtIntLiteral(Type.usize, len_val), | |
| 2516 | fmtIdent("name"), try o.dg.fmtIntLiteral(Type.usize, len_val, .Other), | |
| 2521 | 2517 | }); |
| 2522 | 2518 | |
| 2523 | 2519 | try w.writeAll(" }\n"); |
| ... | ... | @@ -2535,7 +2531,12 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2535 | 2531 | |
| 2536 | 2532 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 2537 | 2533 | try fwd_decl_writer.print("static zig_{s} ", .{@tagName(key)}); |
| 2538 | try o.dg.renderFunctionSignature(fwd_decl_writer, fn_decl_index, .forward, .{ .string = fn_name }); | |
| 2534 | try o.dg.renderFunctionSignature( | |
| 2535 | fwd_decl_writer, | |
| 2536 | fn_decl_index, | |
| 2537 | .forward, | |
| 2538 | .{ .string = fn_name }, | |
| 2539 | ); | |
| 2539 | 2540 | try fwd_decl_writer.writeAll(";\n"); |
| 2540 | 2541 | |
| 2541 | 2542 | try w.print("static zig_{s} ", .{@tagName(key)}); |
| ... | ... | @@ -2753,35 +2754,35 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2753 | 2754 | |
| 2754 | 2755 | // TODO use a different strategy for add, sub, mul, div |
| 2755 | 2756 | // that communicates to the optimizer that wrapping is UB. |
| 2756 | .add => try airBinOp(f, inst, "+", "add", .None), | |
| 2757 | .sub => try airBinOp(f, inst, "-", "sub", .None), | |
| 2758 | .mul => try airBinOp(f, inst, "*", "mul", .None), | |
| 2757 | .add => try airBinOp(f, inst, "+", "add", .none), | |
| 2758 | .sub => try airBinOp(f, inst, "-", "sub", .none), | |
| 2759 | .mul => try airBinOp(f, inst, "*", "mul", .none), | |
| 2759 | 2760 | |
| 2760 | 2761 | .neg => try airFloatNeg(f, inst), |
| 2761 | .div_float => try airBinBuiltinCall(f, inst, "div", .None), | |
| 2762 | .div_float => try airBinBuiltinCall(f, inst, "div", .none), | |
| 2762 | 2763 | |
| 2763 | .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None), | |
| 2764 | .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none), | |
| 2764 | 2765 | .rem => blk: { |
| 2765 | 2766 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2766 | const lhs_ty = f.air.typeOf(bin_op.lhs); | |
| 2767 | const lhs_scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(); | |
| 2767 | 2768 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), |
| 2768 | 2769 | // so we only check one. |
| 2769 | break :blk if (lhs_ty.isInt()) | |
| 2770 | try airBinOp(f, inst, "%", "rem", .None) | |
| 2770 | break :blk if (lhs_scalar_ty.isInt()) | |
| 2771 | try airBinOp(f, inst, "%", "rem", .none) | |
| 2771 | 2772 | else |
| 2772 | 2773 | try airBinFloatOp(f, inst, "fmod"); |
| 2773 | 2774 | }, |
| 2774 | .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None), | |
| 2775 | .mod => try airBinBuiltinCall(f, inst, "mod", .None), | |
| 2775 | .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .none), | |
| 2776 | .mod => try airBinBuiltinCall(f, inst, "mod", .none), | |
| 2776 | 2777 | |
| 2777 | .addwrap => try airBinBuiltinCall(f, inst, "addw", .Bits), | |
| 2778 | .subwrap => try airBinBuiltinCall(f, inst, "subw", .Bits), | |
| 2779 | .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .Bits), | |
| 2778 | .addwrap => try airBinBuiltinCall(f, inst, "addw", .bits), | |
| 2779 | .subwrap => try airBinBuiltinCall(f, inst, "subw", .bits), | |
| 2780 | .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .bits), | |
| 2780 | 2781 | |
| 2781 | .add_sat => try airBinBuiltinCall(f, inst, "adds", .Bits), | |
| 2782 | .sub_sat => try airBinBuiltinCall(f, inst, "subs", .Bits), | |
| 2783 | .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits), | |
| 2784 | .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits), | |
| 2782 | .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits), | |
| 2783 | .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits), | |
| 2784 | .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits), | |
| 2785 | .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits), | |
| 2785 | 2786 | |
| 2786 | 2787 | .sqrt => try airUnFloatOp(f, inst, "sqrt"), |
| 2787 | 2788 | .sin => try airUnFloatOp(f, inst, "sin"), |
| ... | ... | @@ -2800,34 +2801,38 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2800 | 2801 | |
| 2801 | 2802 | .mul_add => try airMulAdd(f, inst), |
| 2802 | 2803 | |
| 2803 | .add_with_overflow => try airOverflow(f, inst, "add", .Bits), | |
| 2804 | .sub_with_overflow => try airOverflow(f, inst, "sub", .Bits), | |
| 2805 | .mul_with_overflow => try airOverflow(f, inst, "mul", .Bits), | |
| 2806 | .shl_with_overflow => try airOverflow(f, inst, "shl", .Bits), | |
| 2804 | .add_with_overflow => try airOverflow(f, inst, "add", .bits), | |
| 2805 | .sub_with_overflow => try airOverflow(f, inst, "sub", .bits), | |
| 2806 | .mul_with_overflow => try airOverflow(f, inst, "mul", .bits), | |
| 2807 | .shl_with_overflow => try airOverflow(f, inst, "shl", .bits), | |
| 2807 | 2808 | |
| 2808 | 2809 | .min => try airMinMax(f, inst, '<', "fmin"), |
| 2809 | 2810 | .max => try airMinMax(f, inst, '>', "fmax"), |
| 2810 | 2811 | |
| 2811 | 2812 | .slice => try airSlice(f, inst), |
| 2812 | 2813 | |
| 2813 | .cmp_gt => try airCmpOp(f, inst, ">", "gt"), | |
| 2814 | .cmp_gte => try airCmpOp(f, inst, ">=", "ge"), | |
| 2815 | .cmp_lt => try airCmpOp(f, inst, "<", "lt"), | |
| 2816 | .cmp_lte => try airCmpOp(f, inst, "<=", "le"), | |
| 2814 | .cmp_gt => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .gt), | |
| 2815 | .cmp_gte => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .gte), | |
| 2816 | .cmp_lt => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .lt), | |
| 2817 | .cmp_lte => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .lte), | |
| 2817 | 2818 | |
| 2818 | .cmp_eq => try airEquality(f, inst, "((", "==", "eq"), | |
| 2819 | .cmp_neq => try airEquality(f, inst, "!((", "!=", "ne"), | |
| 2819 | .cmp_eq => try airEquality(f, inst, .eq), | |
| 2820 | .cmp_neq => try airEquality(f, inst, .neq), | |
| 2820 | 2821 | |
| 2821 | .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}), | |
| 2822 | .cmp_vector => blk: { | |
| 2823 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | |
| 2824 | const extra = f.air.extraData(Air.VectorCmp, ty_pl.payload).data; | |
| 2825 | break :blk try airCmpOp(f, inst, extra, extra.compareOperator()); | |
| 2826 | }, | |
| 2822 | 2827 | .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst), |
| 2823 | 2828 | |
| 2824 | 2829 | // bool_and and bool_or are non-short-circuit operations |
| 2825 | .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .None), | |
| 2826 | .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None), | |
| 2827 | .xor => try airBinOp(f, inst, "^", "xor", .None), | |
| 2828 | .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None), | |
| 2829 | .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits), | |
| 2830 | .shl_exact => try airBinOp(f, inst, "<<", "shl", .None), | |
| 2830 | .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .none), | |
| 2831 | .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .none), | |
| 2832 | .xor => try airBinOp(f, inst, "^", "xor", .none), | |
| 2833 | .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .none), | |
| 2834 | .shl, => try airBinBuiltinCall(f, inst, "shlw", .bits), | |
| 2835 | .shl_exact => try airBinOp(f, inst, "<<", "shl", .none), | |
| 2831 | 2836 | .not => try airNot (f, inst), |
| 2832 | 2837 | |
| 2833 | 2838 | .optional_payload => try airOptionalPayload(f, inst), |
| ... | ... | @@ -2872,11 +2877,11 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2872 | 2877 | .memcpy => try airMemcpy(f, inst), |
| 2873 | 2878 | .set_union_tag => try airSetUnionTag(f, inst), |
| 2874 | 2879 | .get_union_tag => try airGetUnionTag(f, inst), |
| 2875 | .clz => try airUnBuiltinCall(f, inst, "clz", .Bits), | |
| 2876 | .ctz => try airUnBuiltinCall(f, inst, "ctz", .Bits), | |
| 2877 | .popcount => try airUnBuiltinCall(f, inst, "popcount", .Bits), | |
| 2878 | .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .Bits), | |
| 2879 | .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .Bits), | |
| 2880 | .clz => try airUnBuiltinCall(f, inst, "clz", .bits), | |
| 2881 | .ctz => try airUnBuiltinCall(f, inst, "ctz", .bits), | |
| 2882 | .popcount => try airUnBuiltinCall(f, inst, "popcount", .bits), | |
| 2883 | .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .bits), | |
| 2884 | .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .bits), | |
| 2880 | 2885 | .tag_name => try airTagName(f, inst), |
| 2881 | 2886 | .error_name => try airErrorName(f, inst), |
| 2882 | 2887 | .splat => try airSplat(f, inst), |
| ... | ... | @@ -3267,7 +3272,10 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3267 | 3272 | |
| 3268 | 3273 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3269 | 3274 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3270 | const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data; | |
| 3275 | ||
| 3276 | const ptr_ty = f.air.typeOf(ty_op.operand); | |
| 3277 | const ptr_scalar_ty = ptr_ty.scalarType(); | |
| 3278 | const ptr_info = ptr_scalar_ty.ptrInfo().data; | |
| 3271 | 3279 | const src_ty = ptr_info.pointee_type; |
| 3272 | 3280 | |
| 3273 | 3281 | if (!src_ty.hasRuntimeBitsIgnoreComptime() or |
| ... | ... | @@ -3285,20 +3293,23 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3285 | 3293 | const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(target); |
| 3286 | 3294 | const is_array = lowersToArray(src_ty, target); |
| 3287 | 3295 | const need_memcpy = !is_aligned or is_array; |
| 3288 | const writer = f.object.writer(); | |
| 3289 | 3296 | |
| 3297 | const writer = f.object.writer(); | |
| 3290 | 3298 | const local = try f.allocLocal(inst, src_ty); |
| 3299 | const v = try Vectorizer.start(f, inst, writer, ptr_ty); | |
| 3291 | 3300 | |
| 3292 | 3301 | if (need_memcpy) { |
| 3293 | 3302 | try writer.writeAll("memcpy("); |
| 3294 | 3303 | if (!is_array) try writer.writeByte('&'); |
| 3295 | try f.writeCValue(writer, local, .FunctionArgument); | |
| 3304 | try f.writeCValue(writer, local, .Other); | |
| 3305 | try v.elem(f, writer); | |
| 3296 | 3306 | try writer.writeAll(", (const char *)"); |
| 3297 | 3307 | try f.writeCValue(writer, operand, .Other); |
| 3308 | try v.elem(f, writer); | |
| 3298 | 3309 | try writer.writeAll(", sizeof("); |
| 3299 | 3310 | try f.renderType(writer, src_ty); |
| 3300 | 3311 | try writer.writeAll("))"); |
| 3301 | } else if (ptr_info.host_size != 0) { | |
| 3312 | } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) { | |
| 3302 | 3313 | var host_pl = Type.Payload.Bits{ |
| 3303 | 3314 | .base = .{ .tag = .int_unsigned }, |
| 3304 | 3315 | .data = ptr_info.host_size * 8, |
| ... | ... | @@ -3324,6 +3335,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3324 | 3335 | const field_ty = Type.initPayload(&field_pl.base); |
| 3325 | 3336 | |
| 3326 | 3337 | try f.writeCValue(writer, local, .Other); |
| 3338 | try v.elem(f, writer); | |
| 3327 | 3339 | try writer.writeAll(" = ("); |
| 3328 | 3340 | try f.renderType(writer, src_ty); |
| 3329 | 3341 | try writer.writeAll(")zig_wrap_"); |
| ... | ... | @@ -3342,16 +3354,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3342 | 3354 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3343 | 3355 | try writer.writeByte('('); |
| 3344 | 3356 | try f.writeCValueDeref(writer, operand); |
| 3357 | try v.elem(f, writer); | |
| 3345 | 3358 | try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); |
| 3346 | 3359 | if (cant_cast) try writer.writeByte(')'); |
| 3347 | try f.object.dg.renderBuiltinInfo(writer, field_ty, .Bits); | |
| 3360 | try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits); | |
| 3348 | 3361 | try writer.writeByte(')'); |
| 3349 | 3362 | } else { |
| 3350 | 3363 | try f.writeCValue(writer, local, .Other); |
| 3364 | try v.elem(f, writer); | |
| 3351 | 3365 | try writer.writeAll(" = "); |
| 3352 | 3366 | try f.writeCValueDeref(writer, operand); |
| 3367 | try v.elem(f, writer); | |
| 3353 | 3368 | } |
| 3354 | 3369 | try writer.writeAll(";\n"); |
| 3370 | try v.end(f, inst, writer); | |
| 3371 | ||
| 3355 | 3372 | return local; |
| 3356 | 3373 | } |
| 3357 | 3374 | |
| ... | ... | @@ -3417,15 +3434,22 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3417 | 3434 | |
| 3418 | 3435 | const operand = try f.resolveInst(ty_op.operand); |
| 3419 | 3436 | try reap(f, inst, &.{ty_op.operand}); |
| 3420 | const writer = f.object.writer(); | |
| 3437 | ||
| 3421 | 3438 | const inst_ty = f.air.typeOfIndex(inst); |
| 3422 | const local = try f.allocLocal(inst, inst_ty); | |
| 3439 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 3423 | 3440 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3441 | const scalar_ty = operand_ty.scalarType(); | |
| 3424 | 3442 | |
| 3443 | const writer = f.object.writer(); | |
| 3444 | const local = try f.allocLocal(inst, inst_ty); | |
| 3445 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3425 | 3446 | try f.writeCValue(writer, local, .Other); |
| 3447 | try v.elem(f, writer); | |
| 3426 | 3448 | try writer.writeAll(" = "); |
| 3427 | try f.renderIntCast(writer, inst_ty, operand, operand_ty, .Other); | |
| 3449 | try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other); | |
| 3428 | 3450 | try writer.writeAll(";\n"); |
| 3451 | try v.end(f, inst, writer); | |
| 3452 | ||
| 3429 | 3453 | return local; |
| 3430 | 3454 | } |
| 3431 | 3455 | |
| ... | ... | @@ -3439,34 +3463,40 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3439 | 3463 | const operand = try f.resolveInst(ty_op.operand); |
| 3440 | 3464 | try reap(f, inst, &.{ty_op.operand}); |
| 3441 | 3465 | const inst_ty = f.air.typeOfIndex(inst); |
| 3442 | const writer = f.object.writer(); | |
| 3443 | const local = try f.allocLocal(inst, inst_ty); | |
| 3466 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 3444 | 3467 | const target = f.object.dg.module.getTarget(); |
| 3445 | const dest_int_info = inst_ty.intInfo(target); | |
| 3468 | const dest_int_info = inst_scalar_ty.intInfo(target); | |
| 3446 | 3469 | const dest_bits = dest_int_info.bits; |
| 3447 | 3470 | const dest_c_bits = toCIntBits(dest_int_info.bits) orelse |
| 3448 | 3471 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 3449 | 3472 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3450 | const operand_int_info = operand_ty.intInfo(target); | |
| 3473 | const scalar_ty = operand_ty.scalarType(); | |
| 3474 | const scalar_int_info = scalar_ty.intInfo(target); | |
| 3475 | ||
| 3476 | const writer = f.object.writer(); | |
| 3477 | const local = try f.allocLocal(inst, inst_ty); | |
| 3478 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3451 | 3479 | |
| 3452 | 3480 | try f.writeCValue(writer, local, .Other); |
| 3481 | try v.elem(f, writer); | |
| 3453 | 3482 | try writer.writeAll(" = "); |
| 3454 | 3483 | |
| 3455 | 3484 | if (dest_c_bits < 64) { |
| 3456 | 3485 | try writer.writeByte('('); |
| 3457 | try f.renderType(writer, inst_ty); | |
| 3486 | try f.renderType(writer, inst_scalar_ty); | |
| 3458 | 3487 | try writer.writeByte(')'); |
| 3459 | 3488 | } |
| 3460 | 3489 | |
| 3461 | const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64; | |
| 3490 | const needs_lo = scalar_int_info.bits > 64 and dest_bits <= 64; | |
| 3462 | 3491 | if (needs_lo) { |
| 3463 | 3492 | try writer.writeAll("zig_lo_"); |
| 3464 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 3493 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 3465 | 3494 | try writer.writeByte('('); |
| 3466 | 3495 | } |
| 3467 | 3496 | |
| 3468 | 3497 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { |
| 3469 | 3498 | try f.writeCValue(writer, operand, .Other); |
| 3499 | try v.elem(f, writer); | |
| 3470 | 3500 | } else switch (dest_int_info.signedness) { |
| 3471 | 3501 | .unsigned => { |
| 3472 | 3502 | var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa); |
| ... | ... | @@ -3476,15 +3506,16 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3476 | 3506 | var stack align(@alignOf(ExpectedContents)) = |
| 3477 | 3507 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); |
| 3478 | 3508 | |
| 3479 | const mask_val = try inst_ty.maxInt(stack.get(), target); | |
| 3509 | const mask_val = try inst_scalar_ty.maxInt(stack.get(), target); | |
| 3480 | 3510 | try writer.writeAll("zig_and_"); |
| 3481 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 3511 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 3482 | 3512 | try writer.writeByte('('); |
| 3483 | 3513 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3484 | try writer.print(", {x})", .{try f.fmtIntLiteral(operand_ty, mask_val)}); | |
| 3514 | try v.elem(f, writer); | |
| 3515 | try writer.print(", {x})", .{try f.fmtIntLiteral(scalar_ty, mask_val)}); | |
| 3485 | 3516 | }, |
| 3486 | 3517 | .signed => { |
| 3487 | const c_bits = toCIntBits(operand_int_info.bits) orelse | |
| 3518 | const c_bits = toCIntBits(scalar_int_info.bits) orelse | |
| 3488 | 3519 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 3489 | 3520 | var shift_pl = Value.Payload.U64{ |
| 3490 | 3521 | .base = .{ .tag = .int_u64 }, |
| ... | ... | @@ -3493,7 +3524,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3493 | 3524 | const shift_val = Value.initPayload(&shift_pl.base); |
| 3494 | 3525 | |
| 3495 | 3526 | try writer.writeAll("zig_shr_"); |
| 3496 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 3527 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 3497 | 3528 | if (c_bits == 128) { |
| 3498 | 3529 | try writer.print("(zig_bitcast_i{d}(", .{c_bits}); |
| 3499 | 3530 | } else { |
| ... | ... | @@ -3506,6 +3537,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3506 | 3537 | try writer.print("(uint{d}_t)", .{c_bits}); |
| 3507 | 3538 | } |
| 3508 | 3539 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3540 | try v.elem(f, writer); | |
| 3509 | 3541 | if (c_bits == 128) try writer.writeByte(')'); |
| 3510 | 3542 | try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)}); |
| 3511 | 3543 | if (c_bits == 128) try writer.writeByte(')'); |
| ... | ... | @@ -3515,6 +3547,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3515 | 3547 | |
| 3516 | 3548 | if (needs_lo) try writer.writeByte(')'); |
| 3517 | 3549 | try writer.writeAll(";\n"); |
| 3550 | try v.end(f, inst, writer); | |
| 3551 | ||
| 3518 | 3552 | return local; |
| 3519 | 3553 | } |
| 3520 | 3554 | |
| ... | ... | @@ -3551,7 +3585,10 @@ fn storeUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue { |
| 3551 | 3585 | fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3552 | 3586 | // *a = b; |
| 3553 | 3587 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3554 | const ptr_info = f.air.typeOf(bin_op.lhs).ptrInfo().data; | |
| 3588 | ||
| 3589 | const ptr_ty = f.air.typeOf(bin_op.lhs); | |
| 3590 | const ptr_scalar_ty = ptr_ty.scalarType(); | |
| 3591 | const ptr_info = ptr_scalar_ty.ptrInfo().data; | |
| 3555 | 3592 | if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) { |
| 3556 | 3593 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3557 | 3594 | return .none; |
| ... | ... | @@ -3574,11 +3611,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3574 | 3611 | ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(target); |
| 3575 | 3612 | const is_array = lowersToArray(ptr_info.pointee_type, target); |
| 3576 | 3613 | const need_memcpy = !is_aligned or is_array; |
| 3577 | const writer = f.object.writer(); | |
| 3578 | 3614 | |
| 3579 | 3615 | const src_val = try f.resolveInst(bin_op.rhs); |
| 3580 | 3616 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3581 | 3617 | |
| 3618 | const writer = f.object.writer(); | |
| 3619 | const v = try Vectorizer.start(f, inst, writer, ptr_ty); | |
| 3620 | ||
| 3582 | 3621 | if (need_memcpy) { |
| 3583 | 3622 | // For this memcpy to safely work we need the rhs to have the same |
| 3584 | 3623 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). |
| ... | ... | @@ -3599,16 +3638,18 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3599 | 3638 | |
| 3600 | 3639 | try writer.writeAll("memcpy((char *)"); |
| 3601 | 3640 | try f.writeCValue(writer, ptr_val, .FunctionArgument); |
| 3641 | try v.elem(f, writer); | |
| 3602 | 3642 | try writer.writeAll(", "); |
| 3603 | 3643 | if (!is_array) try writer.writeByte('&'); |
| 3604 | 3644 | try f.writeCValue(writer, array_src, .FunctionArgument); |
| 3645 | try v.elem(f, writer); | |
| 3605 | 3646 | try writer.writeAll(", sizeof("); |
| 3606 | 3647 | try f.renderType(writer, src_ty); |
| 3607 | 3648 | try writer.writeAll("))"); |
| 3608 | 3649 | if (src_val == .constant) { |
| 3609 | 3650 | try freeLocal(f, inst, array_src.new_local, 0); |
| 3610 | 3651 | } |
| 3611 | } else if (ptr_info.host_size != 0) { | |
| 3652 | } else if (ptr_info.host_size > 0 and ptr_info.vector_index == .none) { | |
| 3612 | 3653 | const host_bits = ptr_info.host_size * 8; |
| 3613 | 3654 | var host_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = host_bits }; |
| 3614 | 3655 | const host_ty = Type.initPayload(&host_pl.base); |
| ... | ... | @@ -3645,12 +3686,14 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3645 | 3686 | const mask_val = Value.initPayload(&mask_pl.base); |
| 3646 | 3687 | |
| 3647 | 3688 | try f.writeCValueDeref(writer, ptr_val); |
| 3689 | try v.elem(f, writer); | |
| 3648 | 3690 | try writer.writeAll(" = zig_or_"); |
| 3649 | 3691 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3650 | 3692 | try writer.writeAll("(zig_and_"); |
| 3651 | 3693 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3652 | 3694 | try writer.writeByte('('); |
| 3653 | 3695 | try f.writeCValueDeref(writer, ptr_val); |
| 3696 | try v.elem(f, writer); | |
| 3654 | 3697 | try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)}); |
| 3655 | 3698 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3656 | 3699 | try writer.writeByte('('); |
| ... | ... | @@ -3672,14 +3715,19 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3672 | 3715 | try writer.writeByte(')'); |
| 3673 | 3716 | } |
| 3674 | 3717 | try f.writeCValue(writer, src_val, .Other); |
| 3718 | try v.elem(f, writer); | |
| 3675 | 3719 | if (cant_cast) try writer.writeByte(')'); |
| 3676 | 3720 | try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); |
| 3677 | 3721 | } else { |
| 3678 | 3722 | try f.writeCValueDeref(writer, ptr_val); |
| 3723 | try v.elem(f, writer); | |
| 3679 | 3724 | try writer.writeAll(" = "); |
| 3680 | 3725 | try f.writeCValue(writer, src_val, .Other); |
| 3726 | try v.elem(f, writer); | |
| 3681 | 3727 | } |
| 3682 | 3728 | try writer.writeAll(";\n"); |
| 3729 | try v.end(f, inst, writer); | |
| 3730 | ||
| 3683 | 3731 | return .none; |
| 3684 | 3732 | } |
| 3685 | 3733 | |
| ... | ... | @@ -3697,51 +3745,39 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 3697 | 3745 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3698 | 3746 | |
| 3699 | 3747 | const inst_ty = f.air.typeOfIndex(inst); |
| 3700 | const vector_ty = f.air.typeOf(bin_op.lhs); | |
| 3701 | const scalar_ty = vector_ty.scalarType(); | |
| 3702 | const w = f.object.writer(); | |
| 3748 | const operand_ty = f.air.typeOf(bin_op.lhs); | |
| 3749 | const scalar_ty = operand_ty.scalarType(); | |
| 3703 | 3750 | |
| 3751 | const w = f.object.writer(); | |
| 3704 | 3752 | const local = try f.allocLocal(inst, inst_ty); |
| 3705 | ||
| 3706 | switch (vector_ty.zigTypeTag()) { | |
| 3707 | .Vector => { | |
| 3708 | try w.writeAll("zig_v"); | |
| 3709 | try w.writeAll(operation); | |
| 3710 | try w.writeAll("o_"); | |
| 3711 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | |
| 3712 | try w.writeAll("("); | |
| 3713 | try f.writeCValueMember(w, local, .{ .field = 1 }); | |
| 3714 | try w.writeAll(", "); | |
| 3715 | try f.writeCValueMember(w, local, .{ .field = 0 }); | |
| 3716 | try w.print(", {d}, ", .{vector_ty.vectorLen()}); | |
| 3717 | }, | |
| 3718 | else => { | |
| 3719 | try f.writeCValueMember(w, local, .{ .field = 1 }); | |
| 3720 | try w.writeAll(" = zig_"); | |
| 3721 | try w.writeAll(operation); | |
| 3722 | try w.writeAll("o_"); | |
| 3723 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | |
| 3724 | try w.writeAll("(&"); | |
| 3725 | try f.writeCValueMember(w, local, .{ .field = 0 }); | |
| 3726 | try w.writeAll(", "); | |
| 3727 | }, | |
| 3728 | } | |
| 3729 | ||
| 3753 | const v = try Vectorizer.start(f, inst, w, operand_ty); | |
| 3754 | try f.writeCValueMember(w, local, .{ .field = 1 }); | |
| 3755 | try v.elem(f, w); | |
| 3756 | try w.writeAll(" = zig_"); | |
| 3757 | try w.writeAll(operation); | |
| 3758 | try w.writeAll("o_"); | |
| 3759 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | |
| 3760 | try w.writeAll("(&"); | |
| 3761 | try f.writeCValueMember(w, local, .{ .field = 0 }); | |
| 3762 | try v.elem(f, w); | |
| 3763 | try w.writeAll(", "); | |
| 3730 | 3764 | try f.writeCValue(w, lhs, .FunctionArgument); |
| 3765 | try v.elem(f, w); | |
| 3731 | 3766 | try w.writeAll(", "); |
| 3732 | 3767 | try f.writeCValue(w, rhs, .FunctionArgument); |
| 3768 | try v.elem(f, w); | |
| 3733 | 3769 | try f.object.dg.renderBuiltinInfo(w, scalar_ty, info); |
| 3734 | 3770 | try w.writeAll(");\n"); |
| 3771 | try v.end(f, inst, w); | |
| 3735 | 3772 | |
| 3736 | 3773 | return local; |
| 3737 | 3774 | } |
| 3738 | 3775 | |
| 3739 | 3776 | fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3740 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3741 | if (inst_ty.tag() != .bool) | |
| 3742 | return try airUnBuiltinCall(f, inst, "not", .Bits); | |
| 3743 | ||
| 3744 | 3777 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3778 | const operand_ty = f.air.typeOf(ty_op.operand); | |
| 3779 | const scalar_ty = operand_ty.scalarType(); | |
| 3780 | if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits); | |
| 3745 | 3781 | |
| 3746 | 3782 | if (f.liveness.isUnused(inst)) { |
| 3747 | 3783 | try reap(f, inst, &.{ty_op.operand}); |
| ... | ... | @@ -3751,14 +3787,20 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3751 | 3787 | const op = try f.resolveInst(ty_op.operand); |
| 3752 | 3788 | try reap(f, inst, &.{ty_op.operand}); |
| 3753 | 3789 | |
| 3790 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3791 | ||
| 3754 | 3792 | const writer = f.object.writer(); |
| 3755 | 3793 | const local = try f.allocLocal(inst, inst_ty); |
| 3756 | ||
| 3794 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3757 | 3795 | try f.writeCValue(writer, local, .Other); |
| 3796 | try v.elem(f, writer); | |
| 3758 | 3797 | try writer.writeAll(" = "); |
| 3759 | 3798 | try writer.writeByte('!'); |
| 3760 | 3799 | try f.writeCValue(writer, op, .Other); |
| 3800 | try v.elem(f, writer); | |
| 3761 | 3801 | try writer.writeAll(";\n"); |
| 3802 | try v.end(f, inst, writer); | |
| 3803 | ||
| 3762 | 3804 | return local; |
| 3763 | 3805 | } |
| 3764 | 3806 | |
| ... | ... | @@ -3771,63 +3813,89 @@ fn airBinOp( |
| 3771 | 3813 | ) !CValue { |
| 3772 | 3814 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3773 | 3815 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 3816 | const scalar_ty = operand_ty.scalarType(); | |
| 3774 | 3817 | const target = f.object.dg.module.getTarget(); |
| 3775 | if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat()) | |
| 3818 | if ((scalar_ty.isInt() and scalar_ty.bitSize(target) > 64) or scalar_ty.isRuntimeFloat()) | |
| 3776 | 3819 | return try airBinBuiltinCall(f, inst, operation, info); |
| 3777 | 3820 | |
| 3821 | if (f.liveness.isUnused(inst)) { | |
| 3822 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 3823 | return .none; | |
| 3824 | } | |
| 3825 | ||
| 3778 | 3826 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3779 | 3827 | const rhs = try f.resolveInst(bin_op.rhs); |
| 3780 | ||
| 3781 | 3828 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3782 | 3829 | |
| 3783 | if (f.liveness.isUnused(inst)) return .none; | |
| 3784 | ||
| 3785 | 3830 | const inst_ty = f.air.typeOfIndex(inst); |
| 3786 | 3831 | |
| 3787 | 3832 | const writer = f.object.writer(); |
| 3788 | 3833 | const local = try f.allocLocal(inst, inst_ty); |
| 3834 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3789 | 3835 | try f.writeCValue(writer, local, .Other); |
| 3836 | try v.elem(f, writer); | |
| 3790 | 3837 | try writer.writeAll(" = "); |
| 3791 | 3838 | try f.writeCValue(writer, lhs, .Other); |
| 3839 | try v.elem(f, writer); | |
| 3792 | 3840 | try writer.writeByte(' '); |
| 3793 | 3841 | try writer.writeAll(operator); |
| 3794 | 3842 | try writer.writeByte(' '); |
| 3795 | 3843 | try f.writeCValue(writer, rhs, .Other); |
| 3844 | try v.elem(f, writer); | |
| 3796 | 3845 | try writer.writeAll(";\n"); |
| 3846 | try v.end(f, inst, writer); | |
| 3797 | 3847 | |
| 3798 | 3848 | return local; |
| 3799 | 3849 | } |
| 3800 | 3850 | |
| 3801 | fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation: []const u8) !CValue { | |
| 3802 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | |
| 3803 | ||
| 3851 | fn airCmpOp( | |
| 3852 | f: *Function, | |
| 3853 | inst: Air.Inst.Index, | |
| 3854 | data: anytype, | |
| 3855 | operator: std.math.CompareOperator, | |
| 3856 | ) !CValue { | |
| 3804 | 3857 | if (f.liveness.isUnused(inst)) { |
| 3805 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 3858 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 3806 | 3859 | return .none; |
| 3807 | 3860 | } |
| 3808 | 3861 | |
| 3809 | const operand_ty = f.air.typeOf(bin_op.lhs); | |
| 3862 | const operand_ty = f.air.typeOf(data.lhs); | |
| 3863 | const scalar_ty = operand_ty.scalarType(); | |
| 3864 | ||
| 3810 | 3865 | const target = f.object.dg.module.getTarget(); |
| 3811 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) | |
| 3812 | return try cmpBuiltinCall(f, inst, operator, "cmp"); | |
| 3813 | if (operand_ty.isRuntimeFloat()) | |
| 3814 | return try cmpBuiltinCall(f, inst, operator, operation); | |
| 3866 | const scalar_bits = scalar_ty.bitSize(target); | |
| 3867 | if (scalar_ty.isInt() and scalar_bits > 64) | |
| 3868 | return airCmpBuiltinCall( | |
| 3869 | f, | |
| 3870 | inst, | |
| 3871 | data, | |
| 3872 | operator, | |
| 3873 | .cmp, | |
| 3874 | if (scalar_bits > 128) .bits else .none, | |
| 3875 | ); | |
| 3876 | if (scalar_ty.isRuntimeFloat()) | |
| 3877 | return airCmpBuiltinCall(f, inst, data, operator, .operator, .none); | |
| 3815 | 3878 | |
| 3816 | 3879 | const inst_ty = f.air.typeOfIndex(inst); |
| 3817 | const lhs = try f.resolveInst(bin_op.lhs); | |
| 3818 | const rhs = try f.resolveInst(bin_op.rhs); | |
| 3819 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 3880 | const lhs = try f.resolveInst(data.lhs); | |
| 3881 | const rhs = try f.resolveInst(data.rhs); | |
| 3882 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 3820 | 3883 | |
| 3821 | 3884 | const writer = f.object.writer(); |
| 3822 | 3885 | const local = try f.allocLocal(inst, inst_ty); |
| 3886 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3823 | 3887 | try f.writeCValue(writer, local, .Other); |
| 3888 | try v.elem(f, writer); | |
| 3824 | 3889 | try writer.writeAll(" = "); |
| 3825 | 3890 | try f.writeCValue(writer, lhs, .Other); |
| 3891 | try v.elem(f, writer); | |
| 3826 | 3892 | try writer.writeByte(' '); |
| 3827 | try writer.writeAll(operator); | |
| 3893 | try writer.writeAll(compareOperatorC(operator)); | |
| 3828 | 3894 | try writer.writeByte(' '); |
| 3829 | 3895 | try f.writeCValue(writer, rhs, .Other); |
| 3896 | try v.elem(f, writer); | |
| 3830 | 3897 | try writer.writeAll(";\n"); |
| 3898 | try v.end(f, inst, writer); | |
| 3831 | 3899 | |
| 3832 | 3900 | return local; |
| 3833 | 3901 | } |
| ... | ... | @@ -3835,9 +3903,7 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation: |
| 3835 | 3903 | fn airEquality( |
| 3836 | 3904 | f: *Function, |
| 3837 | 3905 | inst: Air.Inst.Index, |
| 3838 | negate_prefix: []const u8, | |
| 3839 | operator: []const u8, | |
| 3840 | operation: []const u8, | |
| 3906 | operator: std.math.CompareOperator, | |
| 3841 | 3907 | ) !CValue { |
| 3842 | 3908 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3843 | 3909 | |
| ... | ... | @@ -3848,10 +3914,18 @@ fn airEquality( |
| 3848 | 3914 | |
| 3849 | 3915 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 3850 | 3916 | const target = f.object.dg.module.getTarget(); |
| 3851 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) | |
| 3852 | return try cmpBuiltinCall(f, inst, operator, "cmp"); | |
| 3917 | const operand_bits = operand_ty.bitSize(target); | |
| 3918 | if (operand_ty.isInt() and operand_bits > 64) | |
| 3919 | return airCmpBuiltinCall( | |
| 3920 | f, | |
| 3921 | inst, | |
| 3922 | bin_op, | |
| 3923 | operator, | |
| 3924 | .cmp, | |
| 3925 | if (operand_bits > 128) .bits else .none, | |
| 3926 | ); | |
| 3853 | 3927 | if (operand_ty.isRuntimeFloat()) |
| 3854 | return try cmpBuiltinCall(f, inst, operator, operation); | |
| 3928 | return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none); | |
| 3855 | 3929 | |
| 3856 | 3930 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3857 | 3931 | const rhs = try f.resolveInst(bin_op.rhs); |
| ... | ... | @@ -3867,7 +3941,12 @@ fn airEquality( |
| 3867 | 3941 | // (A && B) || (C && (A == B)) |
| 3868 | 3942 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload |
| 3869 | 3943 | |
| 3870 | try writer.writeAll(negate_prefix); | |
| 3944 | switch (operator) { | |
| 3945 | .eq => {}, | |
| 3946 | .neq => try writer.writeByte('!'), | |
| 3947 | else => unreachable, | |
| 3948 | } | |
| 3949 | try writer.writeAll("(("); | |
| 3871 | 3950 | try f.writeCValue(writer, lhs, .Other); |
| 3872 | 3951 | try writer.writeAll(".is_null && "); |
| 3873 | 3952 | try f.writeCValue(writer, rhs, .Other); |
| ... | ... | @@ -3886,7 +3965,7 @@ fn airEquality( |
| 3886 | 3965 | |
| 3887 | 3966 | try f.writeCValue(writer, lhs, .Other); |
| 3888 | 3967 | try writer.writeByte(' '); |
| 3889 | try writer.writeAll(operator); | |
| 3968 | try writer.writeAll(compareOperatorC(operator)); | |
| 3890 | 3969 | try writer.writeByte(' '); |
| 3891 | 3970 | try f.writeCValue(writer, rhs, .Other); |
| 3892 | 3971 | try writer.writeAll(";\n"); |
| ... | ... | @@ -3928,11 +4007,14 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3928 | 4007 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3929 | 4008 | |
| 3930 | 4009 | const inst_ty = f.air.typeOfIndex(inst); |
| 3931 | const elem_ty = inst_ty.elemType2(); | |
| 4010 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 4011 | const elem_ty = inst_scalar_ty.elemType2(); | |
| 3932 | 4012 | |
| 3933 | 4013 | const local = try f.allocLocal(inst, inst_ty); |
| 3934 | 4014 | const writer = f.object.writer(); |
| 4015 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 3935 | 4016 | try f.writeCValue(writer, local, .Other); |
| 4017 | try v.elem(f, writer); | |
| 3936 | 4018 | try writer.writeAll(" = "); |
| 3937 | 4019 | |
| 3938 | 4020 | if (elem_ty.hasRuntimeBitsIgnoreComptime()) { |
| ... | ... | @@ -3940,19 +4022,26 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3940 | 4022 | // results in a NULL pointer, or if LHS is NULL. The operation is only UB |
| 3941 | 4023 | // if the result is NULL and then dereferenced. |
| 3942 | 4024 | try writer.writeByte('('); |
| 3943 | try f.renderType(writer, inst_ty); | |
| 4025 | try f.renderType(writer, inst_scalar_ty); | |
| 3944 | 4026 | try writer.writeAll(")(((uintptr_t)"); |
| 3945 | 4027 | try f.writeCValue(writer, lhs, .Other); |
| 4028 | try v.elem(f, writer); | |
| 3946 | 4029 | try writer.writeAll(") "); |
| 3947 | 4030 | try writer.writeByte(operator); |
| 3948 | 4031 | try writer.writeAll(" ("); |
| 3949 | 4032 | try f.writeCValue(writer, rhs, .Other); |
| 4033 | try v.elem(f, writer); | |
| 3950 | 4034 | try writer.writeAll("*sizeof("); |
| 3951 | 4035 | try f.renderType(writer, elem_ty); |
| 3952 | 4036 | try writer.writeAll(")))"); |
| 3953 | } else try f.writeCValue(writer, lhs, .Initializer); | |
| 4037 | } else { | |
| 4038 | try f.writeCValue(writer, lhs, .Other); | |
| 4039 | try v.elem(f, writer); | |
| 4040 | } | |
| 3954 | 4041 | |
| 3955 | 4042 | try writer.writeAll(";\n"); |
| 4043 | try v.end(f, inst, writer); | |
| 4044 | ||
| 3956 | 4045 | return local; |
| 3957 | 4046 | } |
| 3958 | 4047 | |
| ... | ... | @@ -3965,10 +4054,12 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 3965 | 4054 | } |
| 3966 | 4055 | |
| 3967 | 4056 | const inst_ty = f.air.typeOfIndex(inst); |
| 4057 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 4058 | ||
| 3968 | 4059 | const target = f.object.dg.module.getTarget(); |
| 3969 | if (inst_ty.isInt() and inst_ty.bitSize(target) > 64) | |
| 3970 | return try airBinBuiltinCall(f, inst, operation[1..], .None); | |
| 3971 | if (inst_ty.isRuntimeFloat()) | |
| 4060 | if (inst_scalar_ty.isInt() and inst_scalar_ty.bitSize(target) > 64) | |
| 4061 | return try airBinBuiltinCall(f, inst, operation[1..], .none); | |
| 4062 | if (inst_scalar_ty.isRuntimeFloat()) | |
| 3972 | 4063 | return try airBinFloatOp(f, inst, operation); |
| 3973 | 4064 | |
| 3974 | 4065 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3977,19 +4068,26 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 3977 | 4068 | |
| 3978 | 4069 | const writer = f.object.writer(); |
| 3979 | 4070 | const local = try f.allocLocal(inst, inst_ty); |
| 4071 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 3980 | 4072 | try f.writeCValue(writer, local, .Other); |
| 4073 | try v.elem(f, writer); | |
| 3981 | 4074 | // (lhs <> rhs) ? lhs : rhs |
| 3982 | 4075 | try writer.writeAll(" = ("); |
| 3983 | 4076 | try f.writeCValue(writer, lhs, .Other); |
| 4077 | try v.elem(f, writer); | |
| 3984 | 4078 | try writer.writeByte(' '); |
| 3985 | 4079 | try writer.writeByte(operator); |
| 3986 | 4080 | try writer.writeByte(' '); |
| 3987 | 4081 | try f.writeCValue(writer, rhs, .Other); |
| 4082 | try v.elem(f, writer); | |
| 3988 | 4083 | try writer.writeAll(") ? "); |
| 3989 | 4084 | try f.writeCValue(writer, lhs, .Other); |
| 4085 | try v.elem(f, writer); | |
| 3990 | 4086 | try writer.writeAll(" : "); |
| 3991 | 4087 | try f.writeCValue(writer, rhs, .Other); |
| 4088 | try v.elem(f, writer); | |
| 3992 | 4089 | try writer.writeAll(";\n"); |
| 4090 | try v.end(f, inst, writer); | |
| 3993 | 4091 | |
| 3994 | 4092 | return local; |
| 3995 | 4093 | } |
| ... | ... | @@ -4413,12 +4511,56 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4413 | 4511 | |
| 4414 | 4512 | // Ensure padding bits have the expected value. |
| 4415 | 4513 | if (dest_ty.isAbiInt()) { |
| 4514 | const dest_cty = try f.typeToCType(dest_ty, .complete); | |
| 4515 | const dest_info = dest_ty.intInfo(target); | |
| 4516 | var info_ty_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dest_info.signedness) { | |
| 4517 | .unsigned => .int_unsigned, | |
| 4518 | .signed => .int_signed, | |
| 4519 | } }, .data = dest_info.bits }; | |
| 4520 | var wrap_cty: ?CType = null; | |
| 4521 | var need_bitcasts = false; | |
| 4522 | ||
| 4416 | 4523 | try f.writeCValue(writer, local, .Other); |
| 4417 | try writer.writeAll(" = zig_wrap_"); | |
| 4418 | try f.object.dg.renderTypeForBuiltinFnName(writer, dest_ty); | |
| 4524 | if (dest_cty.castTag(.array)) |pl| { | |
| 4525 | try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) { | |
| 4526 | .Little => pl.data.len - 1, | |
| 4527 | .Big => 0, | |
| 4528 | }}); | |
| 4529 | const elem_cty = f.indexToCType(pl.data.elem_type); | |
| 4530 | wrap_cty = elem_cty.toSignedness(dest_info.signedness); | |
| 4531 | need_bitcasts = wrap_cty.?.tag() == .zig_i128; | |
| 4532 | info_ty_pl.data -= 1; | |
| 4533 | info_ty_pl.data %= @intCast(u16, f.byteSize(elem_cty) * 8); | |
| 4534 | info_ty_pl.data += 1; | |
| 4535 | } | |
| 4536 | try writer.writeAll(" = "); | |
| 4537 | if (need_bitcasts) { | |
| 4538 | try writer.writeAll("zig_bitcast_"); | |
| 4539 | try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_cty.?.toUnsigned()); | |
| 4540 | try writer.writeByte('('); | |
| 4541 | } | |
| 4542 | try writer.writeAll("zig_wrap_"); | |
| 4543 | const info_ty = Type.initPayload(&info_ty_pl.base); | |
| 4544 | if (wrap_cty) |cty| | |
| 4545 | try f.object.dg.renderCTypeForBuiltinFnName(writer, cty) | |
| 4546 | else | |
| 4547 | try f.object.dg.renderTypeForBuiltinFnName(writer, info_ty); | |
| 4419 | 4548 | try writer.writeByte('('); |
| 4549 | if (need_bitcasts) { | |
| 4550 | try writer.writeAll("zig_bitcast_"); | |
| 4551 | try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_cty.?); | |
| 4552 | try writer.writeByte('('); | |
| 4553 | } | |
| 4420 | 4554 | try f.writeCValue(writer, local, .Other); |
| 4421 | try f.object.dg.renderBuiltinInfo(writer, dest_ty, .Bits); | |
| 4555 | if (dest_cty.castTag(.array)) |pl| { | |
| 4556 | try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) { | |
| 4557 | .Little => pl.data.len - 1, | |
| 4558 | .Big => 0, | |
| 4559 | }}); | |
| 4560 | } | |
| 4561 | if (need_bitcasts) try writer.writeByte(')'); | |
| 4562 | try f.object.dg.renderBuiltinInfo(writer, info_ty, .bits); | |
| 4563 | if (need_bitcasts) try writer.writeByte(')'); | |
| 4422 | 4564 | try writer.writeAll(");\n"); |
| 4423 | 4565 | } |
| 4424 | 4566 | |
| ... | ... | @@ -5433,7 +5575,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5433 | 5575 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); |
| 5434 | 5576 | try writer.writeByte(')'); |
| 5435 | 5577 | if (cant_cast) try writer.writeByte(')'); |
| 5436 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .Bits); | |
| 5578 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); | |
| 5437 | 5579 | try writer.writeAll(");\n"); |
| 5438 | 5580 | if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local; |
| 5439 | 5581 | |
| ... | ... | @@ -5866,7 +6008,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5866 | 6008 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 5867 | 6009 | try writer.writeByte(')'); |
| 5868 | 6010 | if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) { |
| 5869 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits); | |
| 6011 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits); | |
| 5870 | 6012 | try writer.writeByte(')'); |
| 5871 | 6013 | } |
| 5872 | 6014 | try writer.writeAll(";\n"); |
| ... | ... | @@ -5912,19 +6054,35 @@ fn airUnBuiltinCall( |
| 5912 | 6054 | const operand = try f.resolveInst(ty_op.operand); |
| 5913 | 6055 | try reap(f, inst, &.{ty_op.operand}); |
| 5914 | 6056 | const inst_ty = f.air.typeOfIndex(inst); |
| 6057 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 5915 | 6058 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 6059 | const scalar_ty = operand_ty.scalarType(); | |
| 6060 | ||
| 6061 | const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete); | |
| 6062 | const ref_ret = inst_scalar_cty.tag() == .array; | |
| 5916 | 6063 | |
| 5917 | 6064 | const writer = f.object.writer(); |
| 5918 | 6065 | const local = try f.allocLocal(inst, inst_ty); |
| 5919 | try f.writeCValue(writer, local, .Other); | |
| 5920 | try writer.writeAll(" = zig_"); | |
| 5921 | try writer.writeAll(operation); | |
| 5922 | try writer.writeByte('_'); | |
| 5923 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 6066 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6067 | if (!ref_ret) { | |
| 6068 | try f.writeCValue(writer, local, .Other); | |
| 6069 | try v.elem(f, writer); | |
| 6070 | try writer.writeAll(" = "); | |
| 6071 | } | |
| 6072 | try writer.print("zig_{s}_", .{operation}); | |
| 6073 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 5924 | 6074 | try writer.writeByte('('); |
| 6075 | if (ref_ret) { | |
| 6076 | try f.writeCValue(writer, local, .FunctionArgument); | |
| 6077 | try v.elem(f, writer); | |
| 6078 | try writer.writeAll(", "); | |
| 6079 | } | |
| 5925 | 6080 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 5926 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | |
| 6081 | try v.elem(f, writer); | |
| 6082 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | |
| 5927 | 6083 | try writer.writeAll(");\n"); |
| 6084 | try v.end(f, inst, writer); | |
| 6085 | ||
| 5928 | 6086 | return local; |
| 5929 | 6087 | } |
| 5930 | 6088 | |
| ... | ... | @@ -5946,50 +6104,99 @@ fn airBinBuiltinCall( |
| 5946 | 6104 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 5947 | 6105 | |
| 5948 | 6106 | const inst_ty = f.air.typeOfIndex(inst); |
| 6107 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 5949 | 6108 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 6109 | const scalar_ty = operand_ty.scalarType(); | |
| 6110 | ||
| 6111 | const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete); | |
| 6112 | const ref_ret = inst_scalar_cty.tag() == .array; | |
| 5950 | 6113 | |
| 5951 | 6114 | const writer = f.object.writer(); |
| 5952 | 6115 | const local = try f.allocLocal(inst, inst_ty); |
| 5953 | try f.writeCValue(writer, local, .Other); | |
| 5954 | try writer.writeAll(" = zig_"); | |
| 5955 | try writer.writeAll(operation); | |
| 5956 | try writer.writeByte('_'); | |
| 5957 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 6116 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6117 | if (!ref_ret) { | |
| 6118 | try f.writeCValue(writer, local, .Other); | |
| 6119 | try v.elem(f, writer); | |
| 6120 | try writer.writeAll(" = "); | |
| 6121 | } | |
| 6122 | try writer.print("zig_{s}_", .{operation}); | |
| 6123 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 5958 | 6124 | try writer.writeByte('('); |
| 6125 | if (ref_ret) { | |
| 6126 | try f.writeCValue(writer, local, .FunctionArgument); | |
| 6127 | try v.elem(f, writer); | |
| 6128 | try writer.writeAll(", "); | |
| 6129 | } | |
| 5959 | 6130 | try f.writeCValue(writer, lhs, .FunctionArgument); |
| 6131 | try v.elem(f, writer); | |
| 5960 | 6132 | try writer.writeAll(", "); |
| 5961 | 6133 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 5962 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | |
| 6134 | try v.elem(f, writer); | |
| 6135 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | |
| 5963 | 6136 | try writer.writeAll(");\n"); |
| 6137 | try v.end(f, inst, writer); | |
| 6138 | ||
| 5964 | 6139 | return local; |
| 5965 | 6140 | } |
| 5966 | 6141 | |
| 5967 | fn cmpBuiltinCall( | |
| 6142 | fn airCmpBuiltinCall( | |
| 5968 | 6143 | f: *Function, |
| 5969 | 6144 | inst: Air.Inst.Index, |
| 5970 | operator: []const u8, | |
| 5971 | operation: []const u8, | |
| 6145 | data: anytype, | |
| 6146 | operator: std.math.CompareOperator, | |
| 6147 | operation: enum { cmp, operator }, | |
| 6148 | info: BuiltinInfo, | |
| 5972 | 6149 | ) !CValue { |
| 6150 | if (f.liveness.isUnused(inst)) { | |
| 6151 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 6152 | return .none; | |
| 6153 | } | |
| 6154 | ||
| 6155 | const lhs = try f.resolveInst(data.lhs); | |
| 6156 | const rhs = try f.resolveInst(data.rhs); | |
| 6157 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 6158 | ||
| 5973 | 6159 | const inst_ty = f.air.typeOfIndex(inst); |
| 5974 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | |
| 5975 | const operand_ty = f.air.typeOf(bin_op.lhs); | |
| 6160 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 6161 | const operand_ty = f.air.typeOf(data.lhs); | |
| 6162 | const scalar_ty = operand_ty.scalarType(); | |
| 5976 | 6163 | |
| 5977 | const lhs = try f.resolveInst(bin_op.lhs); | |
| 5978 | const rhs = try f.resolveInst(bin_op.rhs); | |
| 5979 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 6164 | const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete); | |
| 6165 | const ref_ret = inst_scalar_cty.tag() == .array; | |
| 5980 | 6166 | |
| 5981 | 6167 | const writer = f.object.writer(); |
| 5982 | 6168 | const local = try f.allocLocal(inst, inst_ty); |
| 5983 | try f.writeCValue(writer, local, .Other); | |
| 5984 | try writer.writeAll(" = zig_"); | |
| 5985 | try writer.writeAll(operation); | |
| 5986 | try writer.writeByte('_'); | |
| 5987 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 6169 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6170 | if (!ref_ret) { | |
| 6171 | try f.writeCValue(writer, local, .Other); | |
| 6172 | try v.elem(f, writer); | |
| 6173 | try writer.writeAll(" = "); | |
| 6174 | } | |
| 6175 | try writer.print("zig_{s}_", .{switch (operation) { | |
| 6176 | else => @tagName(operation), | |
| 6177 | .operator => compareOperatorAbbrev(operator), | |
| 6178 | }}); | |
| 6179 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 5988 | 6180 | try writer.writeByte('('); |
| 6181 | if (ref_ret) { | |
| 6182 | try f.writeCValue(writer, local, .FunctionArgument); | |
| 6183 | try v.elem(f, writer); | |
| 6184 | try writer.writeAll(", "); | |
| 6185 | } | |
| 5989 | 6186 | try f.writeCValue(writer, lhs, .FunctionArgument); |
| 6187 | try v.elem(f, writer); | |
| 5990 | 6188 | try writer.writeAll(", "); |
| 5991 | 6189 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 5992 | try writer.print(") {s} {};\n", .{ operator, try f.fmtIntLiteral(Type.initTag(.i32), Value.zero) }); | |
| 6190 | try v.elem(f, writer); | |
| 6191 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | |
| 6192 | try writer.writeByte(')'); | |
| 6193 | if (!ref_ret) try writer.print(" {s} {}", .{ | |
| 6194 | compareOperatorC(operator), | |
| 6195 | try f.fmtIntLiteral(Type.initTag(.i32), Value.zero), | |
| 6196 | }); | |
| 6197 | try writer.writeAll(";\n"); | |
| 6198 | try v.end(f, inst, writer); | |
| 6199 | ||
| 5993 | 6200 | return local; |
| 5994 | 6201 | } |
| 5995 | 6202 | |
| ... | ... | @@ -6334,33 +6541,120 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6334 | 6541 | |
| 6335 | 6542 | fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6336 | 6543 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 6544 | ||
| 6337 | 6545 | if (f.liveness.isUnused(inst)) { |
| 6338 | 6546 | try reap(f, inst, &.{ty_op.operand}); |
| 6339 | 6547 | return .none; |
| 6340 | 6548 | } |
| 6341 | 6549 | |
| 6342 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6343 | 6550 | const operand = try f.resolveInst(ty_op.operand); |
| 6344 | 6551 | try reap(f, inst, &.{ty_op.operand}); |
| 6552 | ||
| 6553 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6554 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 6555 | const inst_scalar_cty = try f.typeToIndex(inst_scalar_ty, .complete); | |
| 6556 | const need_memcpy = f.indexToCType(inst_scalar_cty).tag() == .array; | |
| 6557 | ||
| 6345 | 6558 | const writer = f.object.writer(); |
| 6346 | 6559 | const local = try f.allocLocal(inst, inst_ty); |
| 6560 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6561 | if (need_memcpy) try writer.writeAll("memcpy(&"); | |
| 6347 | 6562 | try f.writeCValue(writer, local, .Other); |
| 6348 | try writer.writeAll(" = "); | |
| 6563 | try v.elem(f, writer); | |
| 6564 | try writer.writeAll(if (need_memcpy) ", &" else " = "); | |
| 6565 | try f.writeCValue(writer, operand, .Other); | |
| 6566 | if (need_memcpy) { | |
| 6567 | try writer.writeAll(", sizeof("); | |
| 6568 | try f.renderCType(writer, inst_scalar_cty); | |
| 6569 | try writer.writeAll("))"); | |
| 6570 | } | |
| 6571 | try writer.writeAll(";\n"); | |
| 6572 | try v.end(f, inst, writer); | |
| 6349 | 6573 | |
| 6350 | _ = operand; | |
| 6351 | return f.fail("TODO: C backend: implement airSplat", .{}); | |
| 6574 | return local; | |
| 6352 | 6575 | } |
| 6353 | 6576 | |
| 6354 | 6577 | fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6355 | if (f.liveness.isUnused(inst)) return .none; | |
| 6578 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; | |
| 6579 | const extra = f.air.extraData(Air.Bin, pl_op.payload).data; | |
| 6356 | 6580 | |
| 6357 | return f.fail("TODO: C backend: implement airSelect", .{}); | |
| 6581 | if (f.liveness.isUnused(inst)) { | |
| 6582 | try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs }); | |
| 6583 | return .none; | |
| 6584 | } | |
| 6585 | ||
| 6586 | const pred = try f.resolveInst(pl_op.operand); | |
| 6587 | const lhs = try f.resolveInst(extra.lhs); | |
| 6588 | const rhs = try f.resolveInst(extra.rhs); | |
| 6589 | try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs }); | |
| 6590 | ||
| 6591 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6592 | ||
| 6593 | const writer = f.object.writer(); | |
| 6594 | const local = try f.allocLocal(inst, inst_ty); | |
| 6595 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6596 | try f.writeCValue(writer, local, .Other); | |
| 6597 | try v.elem(f, writer); | |
| 6598 | try writer.writeAll(" = "); | |
| 6599 | try f.writeCValue(writer, pred, .Other); | |
| 6600 | try v.elem(f, writer); | |
| 6601 | try writer.writeAll(" ? "); | |
| 6602 | try f.writeCValue(writer, lhs, .Other); | |
| 6603 | try v.elem(f, writer); | |
| 6604 | try writer.writeAll(" : "); | |
| 6605 | try f.writeCValue(writer, rhs, .Other); | |
| 6606 | try v.elem(f, writer); | |
| 6607 | try writer.writeAll(";\n"); | |
| 6608 | try v.end(f, inst, writer); | |
| 6609 | ||
| 6610 | return local; | |
| 6358 | 6611 | } |
| 6359 | 6612 | |
| 6360 | 6613 | fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6361 | if (f.liveness.isUnused(inst)) return .none; | |
| 6614 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | |
| 6615 | const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data; | |
| 6616 | ||
| 6617 | if (f.liveness.isUnused(inst)) { | |
| 6618 | try reap(f, inst, &.{ extra.a, extra.b }); | |
| 6619 | return .none; | |
| 6620 | } | |
| 6362 | 6621 | |
| 6363 | return f.fail("TODO: C backend: implement airShuffle", .{}); | |
| 6622 | const mask = f.air.values[extra.mask]; | |
| 6623 | const lhs = try f.resolveInst(extra.a); | |
| 6624 | const rhs = try f.resolveInst(extra.b); | |
| 6625 | ||
| 6626 | const module = f.object.dg.module; | |
| 6627 | const target = module.getTarget(); | |
| 6628 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6629 | ||
| 6630 | const writer = f.object.writer(); | |
| 6631 | const local = try f.allocLocal(inst, inst_ty); | |
| 6632 | try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands | |
| 6633 | for (0..extra.mask_len) |index| { | |
| 6634 | var dst_pl = Value.Payload.U64{ | |
| 6635 | .base = .{ .tag = .int_u64 }, | |
| 6636 | .data = @intCast(u64, index), | |
| 6637 | }; | |
| 6638 | ||
| 6639 | try f.writeCValue(writer, local, .Other); | |
| 6640 | try writer.writeByte('['); | |
| 6641 | try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&dst_pl.base), .Other); | |
| 6642 | try writer.writeAll("] = "); | |
| 6643 | ||
| 6644 | var buf: Value.ElemValueBuffer = undefined; | |
| 6645 | const mask_elem = mask.elemValueBuffer(module, index, &buf).toSignedInt(target); | |
| 6646 | var src_pl = Value.Payload.U64{ | |
| 6647 | .base = .{ .tag = .int_u64 }, | |
| 6648 | .data = @intCast(u64, mask_elem ^ mask_elem >> 63), | |
| 6649 | }; | |
| 6650 | ||
| 6651 | try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other); | |
| 6652 | try writer.writeByte('['); | |
| 6653 | try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&src_pl.base), .Other); | |
| 6654 | try writer.writeAll("];\n"); | |
| 6655 | } | |
| 6656 | ||
| 6657 | return local; | |
| 6364 | 6658 | } |
| 6365 | 6659 | |
| 6366 | 6660 | fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | ... | @@ -6376,65 +6670,45 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6376 | 6670 | const operand = try f.resolveInst(reduce.operand); |
| 6377 | 6671 | try reap(f, inst, &.{reduce.operand}); |
| 6378 | 6672 | const operand_ty = f.air.typeOf(reduce.operand); |
| 6379 | const vector_len = operand_ty.vectorLen(); | |
| 6380 | 6673 | const writer = f.object.writer(); |
| 6381 | 6674 | |
| 6382 | const Op = union(enum) { | |
| 6383 | call_fn: []const u8, | |
| 6675 | const use_operator = scalar_ty.bitSize(target) <= 64; | |
| 6676 | const op: union(enum) { | |
| 6677 | const Func = struct { operation: []const u8, info: BuiltinInfo = .none }; | |
| 6678 | float_op: Func, | |
| 6679 | builtin: Func, | |
| 6384 | 6680 | infix: []const u8, |
| 6385 | 6681 | ternary: []const u8, |
| 6386 | }; | |
| 6387 | var fn_name_buf: [64]u8 = undefined; | |
| 6388 | const op: Op = switch (reduce.operation) { | |
| 6389 | .And => .{ .infix = " &= " }, | |
| 6390 | .Or => .{ .infix = " |= " }, | |
| 6391 | .Xor => .{ .infix = " ^= " }, | |
| 6682 | } = switch (reduce.operation) { | |
| 6683 | .And => if (use_operator) .{ .infix = " &= " } else .{ .builtin = .{ .operation = "and" } }, | |
| 6684 | .Or => if (use_operator) .{ .infix = " |= " } else .{ .builtin = .{ .operation = "or" } }, | |
| 6685 | .Xor => if (use_operator) .{ .infix = " ^= " } else .{ .builtin = .{ .operation = "xor" } }, | |
| 6392 | 6686 | .Min => switch (scalar_ty.zigTypeTag()) { |
| 6393 | .Int => Op{ .ternary = " < " }, | |
| 6394 | .Float => op: { | |
| 6395 | const float_bits = scalar_ty.floatBits(target); | |
| 6396 | break :op Op{ | |
| 6397 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "{s}fmin{s}", .{ | |
| 6398 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | |
| 6399 | }) catch unreachable, | |
| 6400 | }; | |
| 6687 | .Int => if (use_operator) .{ .ternary = " < " } else .{ | |
| 6688 | .builtin = .{ .operation = "min" }, | |
| 6401 | 6689 | }, |
| 6690 | .Float => .{ .float_op = .{ .operation = "fmin" } }, | |
| 6402 | 6691 | else => unreachable, |
| 6403 | 6692 | }, |
| 6404 | 6693 | .Max => switch (scalar_ty.zigTypeTag()) { |
| 6405 | .Int => Op{ .ternary = " > " }, | |
| 6406 | .Float => op: { | |
| 6407 | const float_bits = scalar_ty.floatBits(target); | |
| 6408 | break :op Op{ | |
| 6409 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "{s}fmax{s}", .{ | |
| 6410 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | |
| 6411 | }) catch unreachable, | |
| 6412 | }; | |
| 6694 | .Int => if (use_operator) .{ .ternary = " > " } else .{ | |
| 6695 | .builtin = .{ .operation = "max" }, | |
| 6413 | 6696 | }, |
| 6697 | .Float => .{ .float_op = .{ .operation = "fmax" } }, | |
| 6414 | 6698 | else => unreachable, |
| 6415 | 6699 | }, |
| 6416 | 6700 | .Add => switch (scalar_ty.zigTypeTag()) { |
| 6417 | .Int => Op{ .infix = " += " }, | |
| 6418 | .Float => op: { | |
| 6419 | const float_bits = scalar_ty.floatBits(target); | |
| 6420 | break :op Op{ | |
| 6421 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "__add{s}f3", .{ | |
| 6422 | compilerRtFloatAbbrev(float_bits), | |
| 6423 | }) catch unreachable, | |
| 6424 | }; | |
| 6701 | .Int => if (use_operator) .{ .infix = " += " } else .{ | |
| 6702 | .builtin = .{ .operation = "addw", .info = .bits }, | |
| 6425 | 6703 | }, |
| 6704 | .Float => .{ .builtin = .{ .operation = "add" } }, | |
| 6426 | 6705 | else => unreachable, |
| 6427 | 6706 | }, |
| 6428 | 6707 | .Mul => switch (scalar_ty.zigTypeTag()) { |
| 6429 | .Int => Op{ .infix = " *= " }, | |
| 6430 | .Float => op: { | |
| 6431 | const float_bits = scalar_ty.floatBits(target); | |
| 6432 | break :op Op{ | |
| 6433 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "__mul{s}f3", .{ | |
| 6434 | compilerRtFloatAbbrev(float_bits), | |
| 6435 | }) catch unreachable, | |
| 6436 | }; | |
| 6708 | .Int => if (use_operator) .{ .infix = " *= " } else .{ | |
| 6709 | .builtin = .{ .operation = "mulw", .info = .bits }, | |
| 6437 | 6710 | }, |
| 6711 | .Float => .{ .builtin = .{ .operation = "mul" } }, | |
| 6438 | 6712 | else => unreachable, |
| 6439 | 6713 | }, |
| 6440 | 6714 | }; |
| ... | ... | @@ -6450,75 +6724,96 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6450 | 6724 | // } |
| 6451 | 6725 | // break :reduce accum; |
| 6452 | 6726 | // } |
| 6453 | const it = try f.allocLocal(inst, Type.usize); | |
| 6454 | try f.writeCValue(writer, it, .Other); | |
| 6455 | try writer.writeAll(" = 0;\n"); | |
| 6456 | 6727 | |
| 6457 | 6728 | const accum = try f.allocLocal(inst, scalar_ty); |
| 6458 | 6729 | try f.writeCValue(writer, accum, .Other); |
| 6459 | 6730 | try writer.writeAll(" = "); |
| 6460 | 6731 | |
| 6461 | const init_val = switch (reduce.operation) { | |
| 6462 | .And, .Or, .Xor, .Add => "0", | |
| 6732 | var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa); | |
| 6733 | defer arena.deinit(); | |
| 6734 | ||
| 6735 | const ExpectedContents = union { | |
| 6736 | u: Value.Payload.U64, | |
| 6737 | i: Value.Payload.I64, | |
| 6738 | f16: Value.Payload.Float_16, | |
| 6739 | f32: Value.Payload.Float_32, | |
| 6740 | f64: Value.Payload.Float_64, | |
| 6741 | f80: Value.Payload.Float_80, | |
| 6742 | f128: Value.Payload.Float_128, | |
| 6743 | }; | |
| 6744 | var stack align(@alignOf(ExpectedContents)) = | |
| 6745 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | |
| 6746 | ||
| 6747 | try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) { | |
| 6748 | .Or, .Xor, .Add => Value.zero, | |
| 6749 | .And => switch (scalar_ty.zigTypeTag()) { | |
| 6750 | .Bool => Value.one, | |
| 6751 | else => switch (scalar_ty.intInfo(target).signedness) { | |
| 6752 | .unsigned => try scalar_ty.maxInt(stack.get(), target), | |
| 6753 | .signed => Value.negative_one, | |
| 6754 | }, | |
| 6755 | }, | |
| 6463 | 6756 | .Min => switch (scalar_ty.zigTypeTag()) { |
| 6464 | .Int => "TODO_intmax", | |
| 6465 | .Float => "TODO_nan", | |
| 6757 | .Bool => Value.one, | |
| 6758 | .Int => try scalar_ty.maxInt(stack.get(), target), | |
| 6759 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | |
| 6466 | 6760 | else => unreachable, |
| 6467 | 6761 | }, |
| 6468 | 6762 | .Max => switch (scalar_ty.zigTypeTag()) { |
| 6469 | .Int => "TODO_intmin", | |
| 6470 | .Float => "TODO_nan", | |
| 6763 | .Bool => Value.zero, | |
| 6764 | .Int => try scalar_ty.minInt(stack.get(), target), | |
| 6765 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | |
| 6471 | 6766 | else => unreachable, |
| 6472 | 6767 | }, |
| 6473 | .Mul => "1", | |
| 6474 | }; | |
| 6475 | try writer.writeAll(init_val); | |
| 6476 | try writer.writeAll(";"); | |
| 6477 | try f.object.indent_writer.insertNewline(); | |
| 6478 | try writer.writeAll("for (;"); | |
| 6479 | try f.writeCValue(writer, it, .Other); | |
| 6480 | try writer.print("<{d};++", .{vector_len}); | |
| 6481 | try f.writeCValue(writer, it, .Other); | |
| 6482 | try writer.writeAll(") "); | |
| 6483 | try f.writeCValue(writer, accum, .Other); | |
| 6768 | .Mul => Value.one, | |
| 6769 | }, .Initializer); | |
| 6770 | try writer.writeAll(";\n"); | |
| 6484 | 6771 | |
| 6772 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6773 | try f.writeCValue(writer, accum, .Other); | |
| 6485 | 6774 | switch (op) { |
| 6486 | .call_fn => |fn_name| { | |
| 6487 | try writer.print(" = {s}(", .{fn_name}); | |
| 6775 | .float_op => |func| { | |
| 6776 | try writer.writeAll(" = zig_libc_name_"); | |
| 6777 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6778 | try writer.print("({s})(", .{func.operation}); | |
| 6779 | try f.writeCValue(writer, accum, .FunctionArgument); | |
| 6780 | try writer.writeAll(", "); | |
| 6781 | try f.writeCValue(writer, operand, .Other); | |
| 6782 | try v.elem(f, writer); | |
| 6783 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, func.info); | |
| 6784 | try writer.writeByte(')'); | |
| 6785 | }, | |
| 6786 | .builtin => |func| { | |
| 6787 | try writer.print(" = zig_{s}_", .{func.operation}); | |
| 6788 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6789 | try writer.writeByte('('); | |
| 6488 | 6790 | try f.writeCValue(writer, accum, .FunctionArgument); |
| 6489 | 6791 | try writer.writeAll(", "); |
| 6490 | 6792 | try f.writeCValue(writer, operand, .Other); |
| 6491 | try writer.writeAll("["); | |
| 6492 | try f.writeCValue(writer, it, .Other); | |
| 6493 | try writer.writeAll("])"); | |
| 6793 | try v.elem(f, writer); | |
| 6794 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, func.info); | |
| 6795 | try writer.writeByte(')'); | |
| 6494 | 6796 | }, |
| 6495 | 6797 | .infix => |ass| { |
| 6496 | 6798 | try writer.writeAll(ass); |
| 6497 | 6799 | try f.writeCValue(writer, operand, .Other); |
| 6498 | try writer.writeAll("["); | |
| 6499 | try f.writeCValue(writer, it, .Other); | |
| 6500 | try writer.writeAll("]"); | |
| 6800 | try v.elem(f, writer); | |
| 6501 | 6801 | }, |
| 6502 | 6802 | .ternary => |cmp| { |
| 6503 | 6803 | try writer.writeAll(" = "); |
| 6504 | 6804 | try f.writeCValue(writer, accum, .Other); |
| 6505 | 6805 | try writer.writeAll(cmp); |
| 6506 | 6806 | try f.writeCValue(writer, operand, .Other); |
| 6507 | try writer.writeAll("["); | |
| 6508 | try f.writeCValue(writer, it, .Other); | |
| 6509 | try writer.writeAll("] ? "); | |
| 6807 | try v.elem(f, writer); | |
| 6808 | try writer.writeAll(" ? "); | |
| 6510 | 6809 | try f.writeCValue(writer, accum, .Other); |
| 6511 | 6810 | try writer.writeAll(" : "); |
| 6512 | 6811 | try f.writeCValue(writer, operand, .Other); |
| 6513 | try writer.writeAll("["); | |
| 6514 | try f.writeCValue(writer, it, .Other); | |
| 6515 | try writer.writeAll("]"); | |
| 6812 | try v.elem(f, writer); | |
| 6516 | 6813 | }, |
| 6517 | 6814 | } |
| 6518 | ||
| 6519 | 6815 | try writer.writeAll(";\n"); |
| 6520 | ||
| 6521 | try freeLocal(f, inst, it.new_local, 0); | |
| 6816 | try v.end(f, inst, writer); | |
| 6522 | 6817 | |
| 6523 | 6818 | return accum; |
| 6524 | 6819 | } |
| ... | ... | @@ -6652,7 +6947,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6652 | 6947 | try writer.writeByte('('); |
| 6653 | 6948 | |
| 6654 | 6949 | if (inst_ty.isAbiInt() and (field_ty.isAbiInt() or field_ty.isPtrAtRuntime())) { |
| 6655 | try f.renderIntCast(writer, inst_ty, element, field_ty, .FunctionArgument); | |
| 6950 | try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument); | |
| 6656 | 6951 | } else { |
| 6657 | 6952 | try writer.writeByte('('); |
| 6658 | 6953 | try f.renderType(writer, inst_ty); |
| ... | ... | @@ -6670,7 +6965,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6670 | 6965 | |
| 6671 | 6966 | try writer.writeAll(", "); |
| 6672 | 6967 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); |
| 6673 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits); | |
| 6968 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits); | |
| 6674 | 6969 | try writer.writeByte(')'); |
| 6675 | 6970 | if (!empty) try writer.writeByte(')'); |
| 6676 | 6971 | |
| ... | ... | @@ -6794,7 +7089,6 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6794 | 7089 | } |
| 6795 | 7090 | |
| 6796 | 7091 | fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6797 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6798 | 7092 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 6799 | 7093 | if (f.liveness.isUnused(inst)) { |
| 6800 | 7094 | try reap(f, inst, &.{un_op}); |
| ... | ... | @@ -6803,16 +7097,23 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6803 | 7097 | |
| 6804 | 7098 | const operand = try f.resolveInst(un_op); |
| 6805 | 7099 | try reap(f, inst, &.{un_op}); |
| 7100 | ||
| 6806 | 7101 | const operand_ty = f.air.typeOf(un_op); |
| 7102 | const scalar_ty = operand_ty.scalarType(); | |
| 6807 | 7103 | |
| 6808 | 7104 | const writer = f.object.writer(); |
| 6809 | const local = try f.allocLocal(inst, inst_ty); | |
| 7105 | const local = try f.allocLocal(inst, operand_ty); | |
| 7106 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6810 | 7107 | try f.writeCValue(writer, local, .Other); |
| 7108 | try v.elem(f, writer); | |
| 6811 | 7109 | try writer.writeAll(" = zig_neg_"); |
| 6812 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 7110 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6813 | 7111 | try writer.writeByte('('); |
| 6814 | 7112 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 7113 | try v.elem(f, writer); | |
| 6815 | 7114 | try writer.writeAll(");\n"); |
| 7115 | try v.end(f, inst, writer); | |
| 7116 | ||
| 6816 | 7117 | return local; |
| 6817 | 7118 | } |
| 6818 | 7119 | |
| ... | ... | @@ -6822,19 +7123,28 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal |
| 6822 | 7123 | try reap(f, inst, &.{un_op}); |
| 6823 | 7124 | return .none; |
| 6824 | 7125 | } |
| 7126 | ||
| 6825 | 7127 | const operand = try f.resolveInst(un_op); |
| 6826 | 7128 | try reap(f, inst, &.{un_op}); |
| 6827 | const writer = f.object.writer(); | |
| 7129 | ||
| 6828 | 7130 | const inst_ty = f.air.typeOfIndex(inst); |
| 7131 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 7132 | ||
| 7133 | const writer = f.object.writer(); | |
| 6829 | 7134 | const local = try f.allocLocal(inst, inst_ty); |
| 7135 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6830 | 7136 | try f.writeCValue(writer, local, .Other); |
| 7137 | try v.elem(f, writer); | |
| 6831 | 7138 | try writer.writeAll(" = zig_libc_name_"); |
| 6832 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 7139 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); | |
| 6833 | 7140 | try writer.writeByte('('); |
| 6834 | 7141 | try writer.writeAll(operation); |
| 6835 | 7142 | try writer.writeAll(")("); |
| 6836 | 7143 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 7144 | try v.elem(f, writer); | |
| 6837 | 7145 | try writer.writeAll(");\n"); |
| 7146 | try v.end(f, inst, writer); | |
| 7147 | ||
| 6838 | 7148 | return local; |
| 6839 | 7149 | } |
| 6840 | 7150 | |
| ... | ... | @@ -6844,23 +7154,32 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa |
| 6844 | 7154 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6845 | 7155 | return .none; |
| 6846 | 7156 | } |
| 7157 | ||
| 6847 | 7158 | const lhs = try f.resolveInst(bin_op.lhs); |
| 6848 | 7159 | const rhs = try f.resolveInst(bin_op.rhs); |
| 6849 | 7160 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6850 | 7161 | |
| 6851 | const writer = f.object.writer(); | |
| 6852 | 7162 | const inst_ty = f.air.typeOfIndex(inst); |
| 7163 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 7164 | ||
| 7165 | const writer = f.object.writer(); | |
| 6853 | 7166 | const local = try f.allocLocal(inst, inst_ty); |
| 7167 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6854 | 7168 | try f.writeCValue(writer, local, .Other); |
| 7169 | try v.elem(f, writer); | |
| 6855 | 7170 | try writer.writeAll(" = zig_libc_name_"); |
| 6856 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 7171 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); | |
| 6857 | 7172 | try writer.writeByte('('); |
| 6858 | 7173 | try writer.writeAll(operation); |
| 6859 | 7174 | try writer.writeAll(")("); |
| 6860 | 7175 | try f.writeCValue(writer, lhs, .FunctionArgument); |
| 7176 | try v.elem(f, writer); | |
| 6861 | 7177 | try writer.writeAll(", "); |
| 6862 | 7178 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 7179 | try v.elem(f, writer); | |
| 6863 | 7180 | try writer.writeAll(");\n"); |
| 7181 | try v.end(f, inst, writer); | |
| 7182 | ||
| 6864 | 7183 | return local; |
| 6865 | 7184 | } |
| 6866 | 7185 | |
| ... | ... | @@ -6871,23 +7190,34 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6871 | 7190 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand }); |
| 6872 | 7191 | return .none; |
| 6873 | 7192 | } |
| 6874 | const inst_ty = f.air.typeOfIndex(inst); | |
| 7193 | ||
| 6875 | 7194 | const mulend1 = try f.resolveInst(bin_op.lhs); |
| 6876 | 7195 | const mulend2 = try f.resolveInst(bin_op.rhs); |
| 6877 | 7196 | const addend = try f.resolveInst(pl_op.operand); |
| 6878 | 7197 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand }); |
| 7198 | ||
| 7199 | const inst_ty = f.air.typeOfIndex(inst); | |
| 7200 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 7201 | ||
| 6879 | 7202 | const writer = f.object.writer(); |
| 6880 | 7203 | const local = try f.allocLocal(inst, inst_ty); |
| 7204 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6881 | 7205 | try f.writeCValue(writer, local, .Other); |
| 7206 | try v.elem(f, writer); | |
| 6882 | 7207 | try writer.writeAll(" = zig_libc_name_"); |
| 6883 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 7208 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); | |
| 6884 | 7209 | try writer.writeAll("(fma)("); |
| 6885 | 7210 | try f.writeCValue(writer, mulend1, .FunctionArgument); |
| 7211 | try v.elem(f, writer); | |
| 6886 | 7212 | try writer.writeAll(", "); |
| 6887 | 7213 | try f.writeCValue(writer, mulend2, .FunctionArgument); |
| 7214 | try v.elem(f, writer); | |
| 6888 | 7215 | try writer.writeAll(", "); |
| 6889 | 7216 | try f.writeCValue(writer, addend, .FunctionArgument); |
| 7217 | try v.elem(f, writer); | |
| 6890 | 7218 | try writer.writeAll(");\n"); |
| 7219 | try v.end(f, inst, writer); | |
| 7220 | ||
| 6891 | 7221 | return local; |
| 6892 | 7222 | } |
| 6893 | 7223 | |
| ... | ... | @@ -7089,6 +7419,28 @@ fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 { |
| 7089 | 7419 | } else unreachable; |
| 7090 | 7420 | } |
| 7091 | 7421 | |
| 7422 | fn compareOperatorAbbrev(operator: std.math.CompareOperator) []const u8 { | |
| 7423 | return switch (operator) { | |
| 7424 | .lt => "lt", | |
| 7425 | .lte => "le", | |
| 7426 | .eq => "eq", | |
| 7427 | .gte => "ge", | |
| 7428 | .gt => "gt", | |
| 7429 | .neq => "ne", | |
| 7430 | }; | |
| 7431 | } | |
| 7432 | ||
| 7433 | fn compareOperatorC(operator: std.math.CompareOperator) []const u8 { | |
| 7434 | return switch (operator) { | |
| 7435 | .lt => "<", | |
| 7436 | .lte => "<=", | |
| 7437 | .eq => "==", | |
| 7438 | .gte => ">=", | |
| 7439 | .gt => ">", | |
| 7440 | .neq => "!=", | |
| 7441 | }; | |
| 7442 | } | |
| 7443 | ||
| 7092 | 7444 | fn StringLiteral(comptime WriterType: type) type { |
| 7093 | 7445 | // MSVC has a length limit of 16380 per string literal (before concatenation) |
| 7094 | 7446 | const max_char_len = 4; |
| ... | ... | @@ -7177,30 +7529,33 @@ fn undefPattern(comptime IntType: type) IntType { |
| 7177 | 7529 | return @bitCast(IntType, @as(UnsignedType, (1 << (int_info.bits | 1)) / 3)); |
| 7178 | 7530 | } |
| 7179 | 7531 | |
| 7180 | const FormatIntLiteralContext = struct { ty: Type, val: Value, mod: *Module, location: ?ValueRenderLocation = null }; | |
| 7532 | const FormatIntLiteralContext = struct { | |
| 7533 | dg: *DeclGen, | |
| 7534 | int_info: std.builtin.Type.Int, | |
| 7535 | kind: CType.Kind, | |
| 7536 | cty: CType, | |
| 7537 | val: Value, | |
| 7538 | }; | |
| 7181 | 7539 | fn formatIntLiteral( |
| 7182 | 7540 | data: FormatIntLiteralContext, |
| 7183 | 7541 | comptime fmt: []const u8, |
| 7184 | 7542 | options: std.fmt.FormatOptions, |
| 7185 | 7543 | writer: anytype, |
| 7186 | 7544 | ) @TypeOf(writer).Error!void { |
| 7187 | const target = data.mod.getTarget(); | |
| 7188 | const int_info = data.ty.intInfo(target); | |
| 7545 | const target = data.dg.module.getTarget(); | |
| 7189 | 7546 | |
| 7190 | 7547 | const ExpectedContents = struct { |
| 7191 | 7548 | const base = 10; |
| 7192 | const limbs_count_128 = BigInt.calcTwosCompLimbCount(128); | |
| 7193 | const expected_needed_limbs_count = BigInt.calcToStringLimbsBufferLen(limbs_count_128, base); | |
| 7194 | const worst_case_int = BigInt.Const{ | |
| 7195 | .limbs = &([1]BigIntLimb{std.math.maxInt(BigIntLimb)} ** expected_needed_limbs_count), | |
| 7196 | .positive = false, | |
| 7197 | }; | |
| 7549 | const bits = 128; | |
| 7550 | const limbs_count = BigInt.calcTwosCompLimbCount(bits); | |
| 7198 | 7551 | |
| 7199 | undef_limbs: [limbs_count_128]BigIntLimb, | |
| 7200 | wrap_limbs: [limbs_count_128]BigIntLimb, | |
| 7552 | undef_limbs: [limbs_count]BigIntLimb, | |
| 7553 | wrap_limbs: [limbs_count]BigIntLimb, | |
| 7554 | to_string_buf: [bits]u8, | |
| 7555 | to_string_limbs: [BigInt.calcToStringLimbsBufferLen(limbs_count, base)]BigIntLimb, | |
| 7201 | 7556 | }; |
| 7202 | 7557 | var stack align(@alignOf(ExpectedContents)) = |
| 7203 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.mod.gpa); | |
| 7558 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.dg.gpa); | |
| 7204 | 7559 | const allocator = stack.get(); |
| 7205 | 7560 | |
| 7206 | 7561 | var undef_limbs: []BigIntLimb = &.{}; |
| ... | ... | @@ -7208,7 +7563,7 @@ fn formatIntLiteral( |
| 7208 | 7563 | |
| 7209 | 7564 | var int_buf: Value.BigIntSpace = undefined; |
| 7210 | 7565 | const int = if (data.val.isUndefDeep()) blk: { |
| 7211 | undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(int_info.bits)); | |
| 7566 | undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits)); | |
| 7212 | 7567 | std.mem.set(BigIntLimb, undef_limbs, undefPattern(BigIntLimb)); |
| 7213 | 7568 | |
| 7214 | 7569 | var undef_int = BigInt.Mutable{ |
| ... | ... | @@ -7216,164 +7571,193 @@ fn formatIntLiteral( |
| 7216 | 7571 | .len = undef_limbs.len, |
| 7217 | 7572 | .positive = true, |
| 7218 | 7573 | }; |
| 7219 | undef_int.truncate(undef_int.toConst(), int_info.signedness, int_info.bits); | |
| 7574 | undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits); | |
| 7220 | 7575 | break :blk undef_int.toConst(); |
| 7221 | 7576 | } else data.val.toBigInt(&int_buf, target); |
| 7222 | assert(int.fitsInTwosComp(int_info.signedness, int_info.bits)); | |
| 7577 | assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits)); | |
| 7223 | 7578 | |
| 7224 | const c_bits = toCIntBits(int_info.bits) orelse unreachable; | |
| 7579 | const c_bits = @intCast(usize, data.cty.byteSize(data.dg.ctypes.set, target) * 8); | |
| 7225 | 7580 | var one_limbs: [BigInt.calcLimbLen(1)]BigIntLimb = undefined; |
| 7226 | 7581 | const one = BigInt.Mutable.init(&one_limbs, 1).toConst(); |
| 7227 | 7582 | |
| 7228 | const wrap_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)); | |
| 7229 | defer allocator.free(wrap_limbs); | |
| 7230 | var wrap = BigInt.Mutable{ .limbs = wrap_limbs, .len = undefined, .positive = undefined }; | |
| 7231 | if (wrap.addWrap(int, one, int_info.signedness, c_bits) or | |
| 7232 | int_info.signedness == .signed and wrap.subWrap(int, one, int_info.signedness, c_bits)) | |
| 7233 | { | |
| 7234 | const abbrev = switch (data.ty.tag()) { | |
| 7235 | .c_short, .c_ushort => "SHRT", | |
| 7236 | .c_int, .c_uint => "INT", | |
| 7237 | .c_long, .c_ulong => "LONG", | |
| 7238 | .c_longlong, .c_ulonglong => "LLONG", | |
| 7239 | .isize, .usize => "INTPTR", | |
| 7240 | else => return writer.print("zig_{s}Int_{c}{d}", .{ | |
| 7241 | if (int.positive) "max" else "min", signAbbrev(int_info.signedness), c_bits, | |
| 7242 | }), | |
| 7243 | }; | |
| 7244 | if (int_info.signedness == .unsigned) try writer.writeByte('U'); | |
| 7245 | return writer.print("{s}_{s}", .{ abbrev, if (int.positive) "MAX" else "MIN" }); | |
| 7246 | } | |
| 7247 | ||
| 7248 | var use_twos_comp = false; | |
| 7249 | if (!int.positive) { | |
| 7250 | if (c_bits > 64) { | |
| 7251 | // TODO: Can this be done for decimal literals as well? | |
| 7252 | if (fmt.len == 1 and fmt[0] != 'd') { | |
| 7253 | use_twos_comp = true; | |
| 7254 | } else { | |
| 7255 | // TODO: Use fmtIntLiteral for 0? | |
| 7256 | try writer.print("zig_sub_{c}{d}(zig_make_{c}{d}(0, 0), ", .{ signAbbrev(int_info.signedness), c_bits, signAbbrev(int_info.signedness), c_bits }); | |
| 7257 | } | |
| 7258 | } else { | |
| 7259 | try writer.writeByte('-'); | |
| 7260 | } | |
| 7261 | } | |
| 7262 | ||
| 7263 | switch (data.ty.tag()) { | |
| 7264 | .c_short, .c_ushort, .c_int, .c_uint, .c_long, .c_ulong, .c_longlong, .c_ulonglong => {}, | |
| 7265 | else => { | |
| 7266 | if (int_info.bits <= 64) { | |
| 7267 | try writer.print("{s}INT{d}_C(", .{ switch (int_info.signedness) { | |
| 7268 | .signed => "", | |
| 7269 | .unsigned => "U", | |
| 7270 | }, c_bits }); | |
| 7271 | } else if (data.location != null and data.location.? == .StaticInitializer) { | |
| 7272 | // MSVC treats casting the struct initializer as not constant (C2099), so an alternate form is used in global initializers | |
| 7273 | try writer.print("zig_make_constant_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }); | |
| 7274 | } else { | |
| 7275 | try writer.print("zig_make_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }); | |
| 7276 | } | |
| 7583 | var wrap = BigInt.Mutable{ | |
| 7584 | .limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)), | |
| 7585 | .len = undefined, | |
| 7586 | .positive = undefined, | |
| 7587 | }; | |
| 7588 | defer allocator.free(wrap.limbs); | |
| 7589 | ||
| 7590 | const c_limb_info: struct { | |
| 7591 | cty: CType, | |
| 7592 | count: usize, | |
| 7593 | endian: std.builtin.Endian, | |
| 7594 | homogeneous: bool, | |
| 7595 | } = switch (data.cty.tag()) { | |
| 7596 | else => .{ | |
| 7597 | .cty = CType.initTag(.void), | |
| 7598 | .count = 1, | |
| 7599 | .endian = .Little, | |
| 7600 | .homogeneous = true, | |
| 7277 | 7601 | }, |
| 7278 | } | |
| 7602 | .zig_u128, .zig_i128 => .{ | |
| 7603 | .cty = CType.initTag(.uint64_t), | |
| 7604 | .count = 2, | |
| 7605 | .endian = .Big, | |
| 7606 | .homogeneous = false, | |
| 7607 | }, | |
| 7608 | .array => info: { | |
| 7609 | const array_data = data.cty.castTag(.array).?.data; | |
| 7610 | break :info .{ | |
| 7611 | .cty = data.dg.indexToCType(array_data.elem_type), | |
| 7612 | .count = @intCast(usize, array_data.len), | |
| 7613 | .endian = target.cpu.arch.endian(), | |
| 7614 | .homogeneous = true, | |
| 7615 | }; | |
| 7616 | }, | |
| 7617 | }; | |
| 7618 | if (c_limb_info.count == 1) { | |
| 7619 | if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or | |
| 7620 | data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits)) | |
| 7621 | return writer.print("{s}_{s}", .{ | |
| 7622 | data.cty.getStandardDefineAbbrev() orelse return writer.print("zig_{s}Int_{c}{d}", .{ | |
| 7623 | if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits, | |
| 7624 | }), | |
| 7625 | if (int.positive) "MAX" else "MIN", | |
| 7626 | }); | |
| 7279 | 7627 | |
| 7280 | const limbs_count_64 = @divExact(64, @bitSizeOf(BigIntLimb)); | |
| 7281 | if (c_bits <= 64) { | |
| 7282 | var base: u8 = undefined; | |
| 7283 | var case: std.fmt.Case = undefined; | |
| 7284 | switch (fmt.len) { | |
| 7285 | 0 => base = 10, | |
| 7628 | if (!int.positive) try writer.writeByte('-'); | |
| 7629 | try data.cty.renderLiteralPrefix(writer, data.kind); | |
| 7630 | ||
| 7631 | const style: struct { base: u8, case: std.fmt.Case = undefined } = switch (fmt.len) { | |
| 7632 | 0 => .{ .base = 10 }, | |
| 7286 | 7633 | 1 => switch (fmt[0]) { |
| 7287 | 'b' => { | |
| 7288 | base = 2; | |
| 7634 | 'b' => style: { | |
| 7289 | 7635 | try writer.writeAll("0b"); |
| 7636 | break :style .{ .base = 2 }; | |
| 7290 | 7637 | }, |
| 7291 | 'o' => { | |
| 7292 | base = 8; | |
| 7638 | 'o' => style: { | |
| 7293 | 7639 | try writer.writeByte('0'); |
| 7640 | break :style .{ .base = 8 }; | |
| 7294 | 7641 | }, |
| 7295 | 'd' => base = 10, | |
| 7296 | 'x' => { | |
| 7297 | base = 16; | |
| 7298 | case = .lower; | |
| 7299 | try writer.writeAll("0x"); | |
| 7300 | }, | |
| 7301 | 'X' => { | |
| 7302 | base = 16; | |
| 7303 | case = .upper; | |
| 7642 | 'd' => .{ .base = 10 }, | |
| 7643 | 'x', 'X' => |base| style: { | |
| 7304 | 7644 | try writer.writeAll("0x"); |
| 7645 | break :style .{ .base = 16, .case = switch (base) { | |
| 7646 | 'x' => .lower, | |
| 7647 | 'X' => .upper, | |
| 7648 | else => unreachable, | |
| 7649 | } }; | |
| 7305 | 7650 | }, |
| 7306 | 7651 | else => @compileError("Invalid fmt: " ++ fmt), |
| 7307 | 7652 | }, |
| 7308 | 7653 | else => @compileError("Invalid fmt: " ++ fmt), |
| 7309 | } | |
| 7654 | }; | |
| 7310 | 7655 | |
| 7311 | var str: [64]u8 = undefined; | |
| 7312 | var limbs_buf: [BigInt.calcToStringLimbsBufferLen(limbs_count_64, 10)]BigIntLimb = undefined; | |
| 7313 | try writer.writeAll(str[0..int.abs().toString(&str, base, case, &limbs_buf)]); | |
| 7656 | const string = try int.abs().toStringAlloc(allocator, style.base, style.case); | |
| 7657 | defer allocator.free(string); | |
| 7658 | try writer.writeAll(string); | |
| 7314 | 7659 | } else { |
| 7315 | assert(c_bits == 128); | |
| 7316 | const split = std.math.min(int.limbs.len, limbs_count_64); | |
| 7317 | var twos_comp_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined; | |
| 7318 | ||
| 7319 | // Adding a negation in the C code before the doesn't work in all cases: | |
| 7320 | // - struct versions would require an extra zig_sub_ call to negate, which wouldn't work in constant expressions | |
| 7321 | // - negating the f80 int representation (i128) doesn't make sense | |
| 7322 | // Instead we write out the literal as a negative number in twos complement | |
| 7323 | var limbs = int.limbs; | |
| 7324 | ||
| 7325 | if (use_twos_comp) { | |
| 7326 | var twos_comp = BigInt.Mutable{ | |
| 7327 | .limbs = &twos_comp_limbs, | |
| 7328 | .positive = undefined, | |
| 7660 | try data.cty.renderLiteralPrefix(writer, data.kind); | |
| 7661 | wrap.convertToTwosComplement(int, data.int_info.signedness, c_bits); | |
| 7662 | std.mem.set(BigIntLimb, wrap.limbs[wrap.len..], 0); | |
| 7663 | wrap.len = wrap.limbs.len; | |
| 7664 | const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count); | |
| 7665 | ||
| 7666 | var c_limb_int_info = std.builtin.Type.Int{ | |
| 7667 | .signedness = undefined, | |
| 7668 | .bits = @intCast(u16, @divExact(c_bits, c_limb_info.count)), | |
| 7669 | }; | |
| 7670 | var c_limb_cty: CType = undefined; | |
| 7671 | ||
| 7672 | var limb_offset: usize = 0; | |
| 7673 | const most_significant_limb_i = wrap.len - limbs_per_c_limb; | |
| 7674 | while (limb_offset < wrap.len) : (limb_offset += limbs_per_c_limb) { | |
| 7675 | const limb_i = switch (c_limb_info.endian) { | |
| 7676 | .Little => limb_offset, | |
| 7677 | .Big => most_significant_limb_i - limb_offset, | |
| 7678 | }; | |
| 7679 | var c_limb_mut = BigInt.Mutable{ | |
| 7680 | .limbs = wrap.limbs[limb_i..][0..limbs_per_c_limb], | |
| 7329 | 7681 | .len = undefined, |
| 7682 | .positive = true, | |
| 7330 | 7683 | }; |
| 7684 | c_limb_mut.normalize(limbs_per_c_limb); | |
| 7331 | 7685 | |
| 7332 | twos_comp.convertToTwosComplement(int, .signed, int_info.bits); | |
| 7333 | limbs = twos_comp.limbs; | |
| 7686 | if (limb_i == most_significant_limb_i and | |
| 7687 | !c_limb_info.homogeneous and data.int_info.signedness == .signed) | |
| 7688 | { | |
| 7689 | // most significant limb is actually signed | |
| 7690 | c_limb_int_info.signedness = .signed; | |
| 7691 | c_limb_cty = c_limb_info.cty.toSigned(); | |
| 7692 | ||
| 7693 | c_limb_mut.positive = wrap.positive; | |
| 7694 | c_limb_mut.truncate( | |
| 7695 | c_limb_mut.toConst(), | |
| 7696 | .signed, | |
| 7697 | data.int_info.bits - limb_i * @bitSizeOf(BigIntLimb), | |
| 7698 | ); | |
| 7699 | } else { | |
| 7700 | c_limb_int_info.signedness = .unsigned; | |
| 7701 | c_limb_cty = c_limb_info.cty; | |
| 7702 | } | |
| 7703 | var c_limb_val_pl = Value.Payload.BigInt{ | |
| 7704 | .base = .{ .tag = if (c_limb_mut.positive) .int_big_positive else .int_big_negative }, | |
| 7705 | .data = c_limb_mut.limbs[0..c_limb_mut.len], | |
| 7706 | }; | |
| 7707 | ||
| 7708 | if (limb_offset > 0) try writer.writeAll(", "); | |
| 7709 | try formatIntLiteral(.{ | |
| 7710 | .dg = data.dg, | |
| 7711 | .int_info = c_limb_int_info, | |
| 7712 | .kind = data.kind, | |
| 7713 | .cty = c_limb_cty, | |
| 7714 | .val = Value.initPayload(&c_limb_val_pl.base), | |
| 7715 | }, fmt, options, writer); | |
| 7334 | 7716 | } |
| 7717 | } | |
| 7718 | try data.cty.renderLiteralSuffix(writer); | |
| 7719 | } | |
| 7335 | 7720 | |
| 7336 | var upper_pl = Value.Payload.BigInt{ | |
| 7337 | .base = .{ .tag = .int_big_positive }, | |
| 7338 | .data = limbs[split..], | |
| 7339 | }; | |
| 7340 | const upper_val = Value.initPayload(&upper_pl.base); | |
| 7341 | try formatIntLiteral(.{ | |
| 7342 | .ty = switch (int_info.signedness) { | |
| 7343 | .unsigned => Type.u64, | |
| 7344 | .signed => if (use_twos_comp) Type.u64 else Type.i64, | |
| 7345 | }, | |
| 7346 | .val = upper_val, | |
| 7347 | .mod = data.mod, | |
| 7348 | }, fmt, options, writer); | |
| 7721 | const Vectorizer = struct { | |
| 7722 | index: CValue = .none, | |
| 7349 | 7723 | |
| 7350 | try writer.writeAll(", "); | |
| 7724 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorizer { | |
| 7725 | return if (ty.zigTypeTag() == .Vector) index: { | |
| 7726 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() }; | |
| 7351 | 7727 | |
| 7352 | var lower_pl = Value.Payload.BigInt{ | |
| 7353 | .base = .{ .tag = .int_big_positive }, | |
| 7354 | .data = limbs[0..split], | |
| 7355 | }; | |
| 7356 | const lower_val = Value.initPayload(&lower_pl.base); | |
| 7357 | try formatIntLiteral(.{ | |
| 7358 | .ty = Type.u64, | |
| 7359 | .val = lower_val, | |
| 7360 | .mod = data.mod, | |
| 7361 | }, fmt, options, writer); | |
| 7728 | const local = try f.allocLocal(inst, Type.usize); | |
| 7362 | 7729 | |
| 7363 | if (!int.positive and c_bits > 64 and !use_twos_comp) try writer.writeByte(')'); | |
| 7364 | return writer.writeByte(')'); | |
| 7730 | try writer.writeAll("for ("); | |
| 7731 | try f.writeCValue(writer, local, .Other); | |
| 7732 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, Value.zero)}); | |
| 7733 | try f.writeCValue(writer, local, .Other); | |
| 7734 | try writer.print(" < {d}; ", .{ | |
| 7735 | try f.fmtIntLiteral(Type.usize, Value.initPayload(&len_pl.base)), | |
| 7736 | }); | |
| 7737 | try f.writeCValue(writer, local, .Other); | |
| 7738 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, Value.one)}); | |
| 7739 | f.object.indent_writer.pushIndent(); | |
| 7740 | ||
| 7741 | break :index .{ .index = local }; | |
| 7742 | } else .{}; | |
| 7743 | } | |
| 7744 | ||
| 7745 | pub fn elem(self: Vectorizer, f: *Function, writer: anytype) !void { | |
| 7746 | if (self.index != .none) { | |
| 7747 | try writer.writeByte('['); | |
| 7748 | try f.writeCValue(writer, self.index, .Other); | |
| 7749 | try writer.writeByte(']'); | |
| 7750 | } | |
| 7365 | 7751 | } |
| 7366 | 7752 | |
| 7367 | switch (data.ty.tag()) { | |
| 7368 | .c_short, .c_ushort, .c_int => {}, | |
| 7369 | .c_uint => try writer.writeAll("u"), | |
| 7370 | .c_long => try writer.writeAll("l"), | |
| 7371 | .c_ulong => try writer.writeAll("ul"), | |
| 7372 | .c_longlong => try writer.writeAll("ll"), | |
| 7373 | .c_ulonglong => try writer.writeAll("ull"), | |
| 7374 | else => try writer.writeByte(')'), | |
| 7753 | pub fn end(self: Vectorizer, f: *Function, inst: Air.Inst.Index, writer: anytype) !void { | |
| 7754 | if (self.index != .none) { | |
| 7755 | f.object.indent_writer.popIndent(); | |
| 7756 | try writer.writeAll("}\n"); | |
| 7757 | try freeLocal(f, inst, self.index.new_local, 0); | |
| 7758 | } | |
| 7375 | 7759 | } |
| 7376 | } | |
| 7760 | }; | |
| 7377 | 7761 | |
| 7378 | 7762 | fn isByRef(ty: Type) bool { |
| 7379 | 7763 | _ = ty; |
src/codegen/c/type.zig+449-32| ... | ... | @@ -496,6 +496,427 @@ pub const CType = extern union { |
| 496 | 496 | } |
| 497 | 497 | }; |
| 498 | 498 | |
| 499 | pub fn isBool(self: CType) bool { | |
| 500 | return switch (self.tag()) { | |
| 501 | ._Bool, | |
| 502 | .bool, | |
| 503 | => true, | |
| 504 | else => false, | |
| 505 | }; | |
| 506 | } | |
| 507 | ||
| 508 | pub fn isInteger(self: CType) bool { | |
| 509 | return switch (self.tag()) { | |
| 510 | .char, | |
| 511 | .@"signed char", | |
| 512 | .short, | |
| 513 | .int, | |
| 514 | .long, | |
| 515 | .@"long long", | |
| 516 | .@"unsigned char", | |
| 517 | .@"unsigned short", | |
| 518 | .@"unsigned int", | |
| 519 | .@"unsigned long", | |
| 520 | .@"unsigned long long", | |
| 521 | .size_t, | |
| 522 | .ptrdiff_t, | |
| 523 | .uint8_t, | |
| 524 | .int8_t, | |
| 525 | .uint16_t, | |
| 526 | .int16_t, | |
| 527 | .uint32_t, | |
| 528 | .int32_t, | |
| 529 | .uint64_t, | |
| 530 | .int64_t, | |
| 531 | .uintptr_t, | |
| 532 | .intptr_t, | |
| 533 | .zig_u128, | |
| 534 | .zig_i128, | |
| 535 | => true, | |
| 536 | else => false, | |
| 537 | }; | |
| 538 | } | |
| 539 | ||
| 540 | pub fn signedness(self: CType) ?std.builtin.Signedness { | |
| 541 | return switch (self.tag()) { | |
| 542 | .char => null, // unknown signedness | |
| 543 | .@"signed char", | |
| 544 | .short, | |
| 545 | .int, | |
| 546 | .long, | |
| 547 | .@"long long", | |
| 548 | .ptrdiff_t, | |
| 549 | .int8_t, | |
| 550 | .int16_t, | |
| 551 | .int32_t, | |
| 552 | .int64_t, | |
| 553 | .intptr_t, | |
| 554 | .zig_i128, | |
| 555 | => .signed, | |
| 556 | .@"unsigned char", | |
| 557 | .@"unsigned short", | |
| 558 | .@"unsigned int", | |
| 559 | .@"unsigned long", | |
| 560 | .@"unsigned long long", | |
| 561 | .size_t, | |
| 562 | .uint8_t, | |
| 563 | .uint16_t, | |
| 564 | .uint32_t, | |
| 565 | .uint64_t, | |
| 566 | .uintptr_t, | |
| 567 | .zig_u128, | |
| 568 | => .unsigned, | |
| 569 | else => unreachable, | |
| 570 | }; | |
| 571 | } | |
| 572 | ||
| 573 | pub fn isFloat(self: CType) bool { | |
| 574 | return switch (self.tag()) { | |
| 575 | .float, | |
| 576 | .double, | |
| 577 | .@"long double", | |
| 578 | .zig_f16, | |
| 579 | .zig_f32, | |
| 580 | .zig_f64, | |
| 581 | .zig_f80, | |
| 582 | .zig_f128, | |
| 583 | .zig_c_longdouble, | |
| 584 | => true, | |
| 585 | else => false, | |
| 586 | }; | |
| 587 | } | |
| 588 | ||
| 589 | pub fn isPointer(self: CType) bool { | |
| 590 | return switch (self.tag()) { | |
| 591 | .pointer, | |
| 592 | .pointer_const, | |
| 593 | .pointer_volatile, | |
| 594 | .pointer_const_volatile, | |
| 595 | => true, | |
| 596 | else => false, | |
| 597 | }; | |
| 598 | } | |
| 599 | ||
| 600 | pub fn isFunction(self: CType) bool { | |
| 601 | return switch (self.tag()) { | |
| 602 | .function, | |
| 603 | .varargs_function, | |
| 604 | => true, | |
| 605 | else => false, | |
| 606 | }; | |
| 607 | } | |
| 608 | ||
| 609 | pub fn toSigned(self: CType) CType { | |
| 610 | return CType.initTag(switch (self.tag()) { | |
| 611 | .char, .@"signed char", .@"unsigned char" => .@"signed char", | |
| 612 | .short, .@"unsigned short" => .short, | |
| 613 | .int, .@"unsigned int" => .int, | |
| 614 | .long, .@"unsigned long" => .long, | |
| 615 | .@"long long", .@"unsigned long long" => .@"long long", | |
| 616 | .size_t, .ptrdiff_t => .ptrdiff_t, | |
| 617 | .uint8_t, .int8_t => .int8_t, | |
| 618 | .uint16_t, .int16_t => .int16_t, | |
| 619 | .uint32_t, .int32_t => .int32_t, | |
| 620 | .uint64_t, .int64_t => .int64_t, | |
| 621 | .uintptr_t, .intptr_t => .intptr_t, | |
| 622 | .zig_u128, .zig_i128 => .zig_i128, | |
| 623 | .float, | |
| 624 | .double, | |
| 625 | .@"long double", | |
| 626 | .zig_f16, | |
| 627 | .zig_f32, | |
| 628 | .zig_f80, | |
| 629 | .zig_f128, | |
| 630 | .zig_c_longdouble, | |
| 631 | => |t| t, | |
| 632 | else => unreachable, | |
| 633 | }); | |
| 634 | } | |
| 635 | ||
| 636 | pub fn toUnsigned(self: CType) CType { | |
| 637 | return CType.initTag(switch (self.tag()) { | |
| 638 | .char, .@"signed char", .@"unsigned char" => .@"unsigned char", | |
| 639 | .short, .@"unsigned short" => .@"unsigned short", | |
| 640 | .int, .@"unsigned int" => .@"unsigned int", | |
| 641 | .long, .@"unsigned long" => .@"unsigned long", | |
| 642 | .@"long long", .@"unsigned long long" => .@"unsigned long long", | |
| 643 | .size_t, .ptrdiff_t => .size_t, | |
| 644 | .uint8_t, .int8_t => .uint8_t, | |
| 645 | .uint16_t, .int16_t => .uint16_t, | |
| 646 | .uint32_t, .int32_t => .uint32_t, | |
| 647 | .uint64_t, .int64_t => .uint64_t, | |
| 648 | .uintptr_t, .intptr_t => .uintptr_t, | |
| 649 | .zig_u128, .zig_i128 => .zig_u128, | |
| 650 | else => unreachable, | |
| 651 | }); | |
| 652 | } | |
| 653 | ||
| 654 | pub fn toSignedness(self: CType, s: std.builtin.Signedness) CType { | |
| 655 | return switch (s) { | |
| 656 | .unsigned => self.toUnsigned(), | |
| 657 | .signed => self.toSigned(), | |
| 658 | }; | |
| 659 | } | |
| 660 | ||
| 661 | pub fn getStandardDefineAbbrev(self: CType) ?[]const u8 { | |
| 662 | return switch (self.tag()) { | |
| 663 | .char => "CHAR", | |
| 664 | .@"signed char" => "SCHAR", | |
| 665 | .short => "SHRT", | |
| 666 | .int => "INT", | |
| 667 | .long => "LONG", | |
| 668 | .@"long long" => "LLONG", | |
| 669 | .@"unsigned char" => "UCHAR", | |
| 670 | .@"unsigned short" => "USHRT", | |
| 671 | .@"unsigned int" => "UINT", | |
| 672 | .@"unsigned long" => "ULONG", | |
| 673 | .@"unsigned long long" => "ULLONG", | |
| 674 | .float => "FLT", | |
| 675 | .double => "DBL", | |
| 676 | .@"long double" => "LDBL", | |
| 677 | .size_t => "SIZE", | |
| 678 | .ptrdiff_t => "PTRDIFF", | |
| 679 | .uint8_t => "UINT8", | |
| 680 | .int8_t => "INT8", | |
| 681 | .uint16_t => "UINT16", | |
| 682 | .int16_t => "INT16", | |
| 683 | .uint32_t => "UINT32", | |
| 684 | .int32_t => "INT32", | |
| 685 | .uint64_t => "UINT64", | |
| 686 | .int64_t => "INT64", | |
| 687 | .uintptr_t => "UINTPTR", | |
| 688 | .intptr_t => "INTPTR", | |
| 689 | else => null, | |
| 690 | }; | |
| 691 | } | |
| 692 | ||
| 693 | pub fn renderLiteralPrefix(self: CType, writer: anytype, kind: Kind) @TypeOf(writer).Error!void { | |
| 694 | switch (self.tag()) { | |
| 695 | .void => unreachable, | |
| 696 | ._Bool, | |
| 697 | .char, | |
| 698 | .@"signed char", | |
| 699 | .short, | |
| 700 | .@"unsigned short", | |
| 701 | .bool, | |
| 702 | .size_t, | |
| 703 | .ptrdiff_t, | |
| 704 | .uintptr_t, | |
| 705 | .intptr_t, | |
| 706 | => |t| switch (kind) { | |
| 707 | else => try writer.print("({s})", .{@tagName(t)}), | |
| 708 | .global => {}, | |
| 709 | }, | |
| 710 | .int, | |
| 711 | .long, | |
| 712 | .@"long long", | |
| 713 | .@"unsigned char", | |
| 714 | .@"unsigned int", | |
| 715 | .@"unsigned long", | |
| 716 | .@"unsigned long long", | |
| 717 | .float, | |
| 718 | .double, | |
| 719 | .@"long double", | |
| 720 | => {}, | |
| 721 | .uint8_t, | |
| 722 | .int8_t, | |
| 723 | .uint16_t, | |
| 724 | .int16_t, | |
| 725 | .uint32_t, | |
| 726 | .int32_t, | |
| 727 | .uint64_t, | |
| 728 | .int64_t, | |
| 729 | => try writer.print("{s}_C(", .{self.getStandardDefineAbbrev().?}), | |
| 730 | .zig_u128, | |
| 731 | .zig_i128, | |
| 732 | .zig_f16, | |
| 733 | .zig_f32, | |
| 734 | .zig_f64, | |
| 735 | .zig_f80, | |
| 736 | .zig_f128, | |
| 737 | .zig_c_longdouble, | |
| 738 | => |t| try writer.print("zig_{s}_{s}(", .{ | |
| 739 | switch (kind) { | |
| 740 | else => "make", | |
| 741 | .global => "init", | |
| 742 | }, | |
| 743 | @tagName(t)["zig_".len..], | |
| 744 | }), | |
| 745 | .pointer, | |
| 746 | .pointer_const, | |
| 747 | .pointer_volatile, | |
| 748 | .pointer_const_volatile, | |
| 749 | => unreachable, | |
| 750 | .array, | |
| 751 | .vector, | |
| 752 | => try writer.writeByte('{'), | |
| 753 | .fwd_anon_struct, | |
| 754 | .fwd_anon_union, | |
| 755 | .fwd_struct, | |
| 756 | .fwd_union, | |
| 757 | .unnamed_struct, | |
| 758 | .unnamed_union, | |
| 759 | .packed_unnamed_struct, | |
| 760 | .packed_unnamed_union, | |
| 761 | .anon_struct, | |
| 762 | .anon_union, | |
| 763 | .@"struct", | |
| 764 | .@"union", | |
| 765 | .packed_struct, | |
| 766 | .packed_union, | |
| 767 | .function, | |
| 768 | .varargs_function, | |
| 769 | => unreachable, | |
| 770 | } | |
| 771 | } | |
| 772 | ||
| 773 | pub fn renderLiteralSuffix(self: CType, writer: anytype) @TypeOf(writer).Error!void { | |
| 774 | switch (self.tag()) { | |
| 775 | .void => unreachable, | |
| 776 | ._Bool => {}, | |
| 777 | .char, | |
| 778 | .@"signed char", | |
| 779 | .short, | |
| 780 | .int, | |
| 781 | => {}, | |
| 782 | .long => try writer.writeByte('l'), | |
| 783 | .@"long long" => try writer.writeAll("ll"), | |
| 784 | .@"unsigned char", | |
| 785 | .@"unsigned short", | |
| 786 | .@"unsigned int", | |
| 787 | => try writer.writeByte('u'), | |
| 788 | .@"unsigned long", | |
| 789 | .size_t, | |
| 790 | .uintptr_t, | |
| 791 | => try writer.writeAll("ul"), | |
| 792 | .@"unsigned long long" => try writer.writeAll("ull"), | |
| 793 | .float => try writer.writeByte('f'), | |
| 794 | .double => {}, | |
| 795 | .@"long double" => try writer.writeByte('l'), | |
| 796 | .bool, | |
| 797 | .ptrdiff_t, | |
| 798 | .intptr_t, | |
| 799 | => {}, | |
| 800 | .uint8_t, | |
| 801 | .int8_t, | |
| 802 | .uint16_t, | |
| 803 | .int16_t, | |
| 804 | .uint32_t, | |
| 805 | .int32_t, | |
| 806 | .uint64_t, | |
| 807 | .int64_t, | |
| 808 | .zig_u128, | |
| 809 | .zig_i128, | |
| 810 | .zig_f16, | |
| 811 | .zig_f32, | |
| 812 | .zig_f64, | |
| 813 | .zig_f80, | |
| 814 | .zig_f128, | |
| 815 | .zig_c_longdouble, | |
| 816 | => try writer.writeByte(')'), | |
| 817 | .pointer, | |
| 818 | .pointer_const, | |
| 819 | .pointer_volatile, | |
| 820 | .pointer_const_volatile, | |
| 821 | => unreachable, | |
| 822 | .array, | |
| 823 | .vector, | |
| 824 | => try writer.writeByte('}'), | |
| 825 | .fwd_anon_struct, | |
| 826 | .fwd_anon_union, | |
| 827 | .fwd_struct, | |
| 828 | .fwd_union, | |
| 829 | .unnamed_struct, | |
| 830 | .unnamed_union, | |
| 831 | .packed_unnamed_struct, | |
| 832 | .packed_unnamed_union, | |
| 833 | .anon_struct, | |
| 834 | .anon_union, | |
| 835 | .@"struct", | |
| 836 | .@"union", | |
| 837 | .packed_struct, | |
| 838 | .packed_union, | |
| 839 | .function, | |
| 840 | .varargs_function, | |
| 841 | => unreachable, | |
| 842 | } | |
| 843 | } | |
| 844 | ||
| 845 | pub fn floatActiveBits(self: CType, target: Target) u16 { | |
| 846 | return switch (self.tag()) { | |
| 847 | .float => target.c_type_bit_size(.float), | |
| 848 | .double => target.c_type_bit_size(.double), | |
| 849 | .@"long double", .zig_c_longdouble => target.c_type_bit_size(.longdouble), | |
| 850 | .zig_f16 => 16, | |
| 851 | .zig_f32 => 32, | |
| 852 | .zig_f64 => 64, | |
| 853 | .zig_f80 => 80, | |
| 854 | .zig_f128 => 128, | |
| 855 | else => unreachable, | |
| 856 | }; | |
| 857 | } | |
| 858 | ||
| 859 | pub fn byteSize(self: CType, store: Store.Set, target: Target) u64 { | |
| 860 | return switch (self.tag()) { | |
| 861 | .void => 0, | |
| 862 | .char, .@"signed char", ._Bool, .@"unsigned char", .bool, .uint8_t, .int8_t => 1, | |
| 863 | .short => target.c_type_byte_size(.short), | |
| 864 | .int => target.c_type_byte_size(.int), | |
| 865 | .long => target.c_type_byte_size(.long), | |
| 866 | .@"long long" => target.c_type_byte_size(.longlong), | |
| 867 | .@"unsigned short" => target.c_type_byte_size(.ushort), | |
| 868 | .@"unsigned int" => target.c_type_byte_size(.uint), | |
| 869 | .@"unsigned long" => target.c_type_byte_size(.ulong), | |
| 870 | .@"unsigned long long" => target.c_type_byte_size(.ulonglong), | |
| 871 | .float => target.c_type_byte_size(.float), | |
| 872 | .double => target.c_type_byte_size(.double), | |
| 873 | .@"long double" => target.c_type_byte_size(.longdouble), | |
| 874 | .size_t, | |
| 875 | .ptrdiff_t, | |
| 876 | .uintptr_t, | |
| 877 | .intptr_t, | |
| 878 | .pointer, | |
| 879 | .pointer_const, | |
| 880 | .pointer_volatile, | |
| 881 | .pointer_const_volatile, | |
| 882 | => @divExact(target.cpu.arch.ptrBitWidth(), 8), | |
| 883 | .uint16_t, .int16_t, .zig_f16 => 2, | |
| 884 | .uint32_t, .int32_t, .zig_f32 => 4, | |
| 885 | .uint64_t, .int64_t, .zig_f64 => 8, | |
| 886 | .zig_u128, .zig_i128, .zig_f128 => 16, | |
| 887 | .zig_f80 => if (target.c_type_bit_size(.longdouble) == 80) | |
| 888 | target.c_type_byte_size(.longdouble) | |
| 889 | else | |
| 890 | 16, | |
| 891 | .zig_c_longdouble => target.c_type_byte_size(.longdouble), | |
| 892 | ||
| 893 | .array, | |
| 894 | .vector, | |
| 895 | => { | |
| 896 | const data = self.cast(Payload.Sequence).?.data; | |
| 897 | return data.len * store.indexToCType(data.elem_type).byteSize(store, target); | |
| 898 | }, | |
| 899 | ||
| 900 | .fwd_anon_struct, | |
| 901 | .fwd_anon_union, | |
| 902 | .fwd_struct, | |
| 903 | .fwd_union, | |
| 904 | .unnamed_struct, | |
| 905 | .unnamed_union, | |
| 906 | .packed_unnamed_struct, | |
| 907 | .packed_unnamed_union, | |
| 908 | .anon_struct, | |
| 909 | .anon_union, | |
| 910 | .@"struct", | |
| 911 | .@"union", | |
| 912 | .packed_struct, | |
| 913 | .packed_union, | |
| 914 | .function, | |
| 915 | .varargs_function, | |
| 916 | => unreachable, | |
| 917 | }; | |
| 918 | } | |
| 919 | ||
| 499 | 920 | pub fn isPacked(self: CType) bool { |
| 500 | 921 | return switch (self.tag()) { |
| 501 | 922 | else => false, |
| ... | ... | @@ -787,26 +1208,26 @@ pub const CType = extern union { |
| 787 | 1208 | }; |
| 788 | 1209 | } |
| 789 | 1210 | |
| 790 | fn tagFromIntInfo(signedness: std.builtin.Signedness, bits: u16) Tag { | |
| 791 | return switch (bits) { | |
| 1211 | fn tagFromIntInfo(int_info: std.builtin.Type.Int) Tag { | |
| 1212 | return switch (int_info.bits) { | |
| 792 | 1213 | 0 => .void, |
| 793 | 1...8 => switch (signedness) { | |
| 1214 | 1...8 => switch (int_info.signedness) { | |
| 794 | 1215 | .unsigned => .uint8_t, |
| 795 | 1216 | .signed => .int8_t, |
| 796 | 1217 | }, |
| 797 | 9...16 => switch (signedness) { | |
| 1218 | 9...16 => switch (int_info.signedness) { | |
| 798 | 1219 | .unsigned => .uint16_t, |
| 799 | 1220 | .signed => .int16_t, |
| 800 | 1221 | }, |
| 801 | 17...32 => switch (signedness) { | |
| 1222 | 17...32 => switch (int_info.signedness) { | |
| 802 | 1223 | .unsigned => .uint32_t, |
| 803 | 1224 | .signed => .int32_t, |
| 804 | 1225 | }, |
| 805 | 33...64 => switch (signedness) { | |
| 1226 | 33...64 => switch (int_info.signedness) { | |
| 806 | 1227 | .unsigned => .uint64_t, |
| 807 | 1228 | .signed => .int64_t, |
| 808 | 1229 | }, |
| 809 | 65...128 => switch (signedness) { | |
| 1230 | 65...128 => switch (int_info.signedness) { | |
| 810 | 1231 | .unsigned => .zig_u128, |
| 811 | 1232 | .signed => .zig_i128, |
| 812 | 1233 | }, |
| ... | ... | @@ -945,31 +1366,27 @@ pub const CType = extern union { |
| 945 | 1366 | .c_ulong => self.init(.@"unsigned long"), |
| 946 | 1367 | .c_longlong => self.init(.@"long long"), |
| 947 | 1368 | .c_ulonglong => self.init(.@"unsigned long long"), |
| 948 | else => { | |
| 949 | const info = ty.intInfo(target); | |
| 950 | const t = tagFromIntInfo(info.signedness, info.bits); | |
| 951 | switch (t) { | |
| 952 | .void => unreachable, | |
| 953 | else => self.init(t), | |
| 954 | .array => switch (kind) { | |
| 955 | .forward, .complete, .global => { | |
| 956 | const abi_size = ty.abiSize(target); | |
| 957 | const abi_align = ty.abiAlignment(target); | |
| 958 | self.storage = .{ .seq = .{ .base = .{ .tag = .array }, .data = .{ | |
| 959 | .len = @divExact(abi_size, abi_align), | |
| 960 | .elem_type = tagFromIntInfo( | |
| 961 | .unsigned, | |
| 962 | @intCast(u16, abi_align * 8), | |
| 963 | ).toIndex(), | |
| 964 | } } }; | |
| 965 | self.value = .{ .cty = initPayload(&self.storage.seq) }; | |
| 966 | }, | |
| 967 | .forward_parameter, | |
| 968 | .parameter, | |
| 969 | => try self.initArrayParameter(ty, kind, lookup), | |
| 970 | .payload => unreachable, | |
| 1369 | else => switch (tagFromIntInfo(ty.intInfo(target))) { | |
| 1370 | .void => unreachable, | |
| 1371 | else => |t| self.init(t), | |
| 1372 | .array => switch (kind) { | |
| 1373 | .forward, .complete, .global => { | |
| 1374 | const abi_size = ty.abiSize(target); | |
| 1375 | const abi_align = ty.abiAlignment(target); | |
| 1376 | self.storage = .{ .seq = .{ .base = .{ .tag = .array }, .data = .{ | |
| 1377 | .len = @divExact(abi_size, abi_align), | |
| 1378 | .elem_type = tagFromIntInfo(.{ | |
| 1379 | .signedness = .unsigned, | |
| 1380 | .bits = @intCast(u16, abi_align * 8), | |
| 1381 | }).toIndex(), | |
| 1382 | } } }; | |
| 1383 | self.value = .{ .cty = initPayload(&self.storage.seq) }; | |
| 971 | 1384 | }, |
| 972 | } | |
| 1385 | .forward_parameter, | |
| 1386 | .parameter, | |
| 1387 | => try self.initArrayParameter(ty, kind, lookup), | |
| 1388 | .payload => unreachable, | |
| 1389 | }, | |
| 973 | 1390 | }, |
| 974 | 1391 | } else switch (ty.zigTypeTag()) { |
| 975 | 1392 | .Frame => unreachable, |
| ... | ... | @@ -1048,7 +1465,7 @@ pub const CType = extern union { |
| 1048 | 1465 | .base = .{ .tag = .int_unsigned }, |
| 1049 | 1466 | .data = info.host_size * 8, |
| 1050 | 1467 | }; |
| 1051 | const pointee_ty = if (info.host_size > 0) | |
| 1468 | const pointee_ty = if (info.host_size > 0 and info.vector_index == .none) | |
| 1052 | 1469 | Type.initPayload(&host_int_pl.base) |
| 1053 | 1470 | else |
| 1054 | 1471 | info.pointee_type; |
src/link/C.zig+14-8| ... | ... | @@ -221,14 +221,19 @@ pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void |
| 221 | 221 | return self.flushModule(comp, prog_node); |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | fn abiDefine(comp: *Compilation) ?[]const u8 { | |
| 225 | return switch (comp.getTarget().abi) { | |
| 226 | .msvc => "#define ZIG_TARGET_ABI_MSVC\n", | |
| 227 | else => null, | |
| 228 | }; | |
| 224 | fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { | |
| 225 | var defines = std.ArrayList(u8).init(self.base.allocator); | |
| 226 | errdefer defines.deinit(); | |
| 227 | const writer = defines.writer(); | |
| 228 | switch (target.abi) { | |
| 229 | .msvc => try writer.writeAll("#define ZIG_TARGET_ABI_MSVC\n"), | |
| 230 | else => {}, | |
| 231 | } | |
| 232 | try writer.print("#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n", .{target.maxIntAlignment()}); | |
| 233 | return defines; | |
| 229 | 234 | } |
| 230 | 235 | |
| 231 | pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 236 | pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 232 | 237 | const tracy = trace(@src()); |
| 233 | 238 | defer tracy.end(); |
| 234 | 239 | |
| ... | ... | @@ -245,12 +250,13 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) |
| 245 | 250 | var f: Flush = .{}; |
| 246 | 251 | defer f.deinit(gpa); |
| 247 | 252 | |
| 248 | const abi_define = abiDefine(comp); | |
| 253 | const abi_defines = try self.abiDefines(module.getTarget()); | |
| 254 | defer abi_defines.deinit(); | |
| 249 | 255 | |
| 250 | 256 | // Covers defines, zig.h, ctypes, asm, lazy fwd. |
| 251 | 257 | try f.all_buffers.ensureUnusedCapacity(gpa, 5); |
| 252 | 258 | |
| 253 | if (abi_define) |buf| f.appendBufAssumeCapacity(buf); | |
| 259 | f.appendBufAssumeCapacity(abi_defines.items); | |
| 254 | 260 | f.appendBufAssumeCapacity(zig_h); |
| 255 | 261 | |
| 256 | 262 | const ctypes_index = f.all_buffers.items.len; |
src/value.zig+1-1| ... | ... | @@ -3319,7 +3319,7 @@ pub const Value = extern union { |
| 3319 | 3319 | } |
| 3320 | 3320 | } |
| 3321 | 3321 | |
| 3322 | fn floatToValue(float: f128, arena: Allocator, dest_ty: Type, target: Target) !Value { | |
| 3322 | pub fn floatToValue(float: f128, arena: Allocator, dest_ty: Type, target: Target) !Value { | |
| 3323 | 3323 | switch (dest_ty.floatBits(target)) { |
| 3324 | 3324 | 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)), |
| 3325 | 3325 | 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)), |
test/behavior/bitcast.zig-3| ... | ... | @@ -34,7 +34,6 @@ test "@bitCast iX -> uX (8, 16, 128)" { |
| 34 | 34 | |
| 35 | 35 | test "@bitCast iX -> uX exotic integers" { |
| 36 | 36 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 37 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 38 | 37 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 39 | 38 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 40 | 39 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | ... | @@ -81,7 +80,6 @@ fn conv_uN(comptime N: usize, x: std.meta.Int(.unsigned, N)) std.meta.Int(.signe |
| 81 | 80 | |
| 82 | 81 | test "bitcast uX to bytes" { |
| 83 | 82 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 84 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 85 | 83 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 86 | 84 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 87 | 85 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | ... | @@ -368,7 +366,6 @@ test "comptime @bitCast packed struct to int and back" { |
| 368 | 366 | } |
| 369 | 367 | |
| 370 | 368 | test "comptime bitcast with fields following f80" { |
| 371 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 372 | 369 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 373 | 370 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 374 | 371 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
test/behavior/bitreverse.zig-3| ... | ... | @@ -96,7 +96,6 @@ fn vector8() !void { |
| 96 | 96 | |
| 97 | 97 | test "bitReverse vectors u8" { |
| 98 | 98 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 99 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 100 | 99 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 101 | 100 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 102 | 101 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | ... | @@ -115,7 +114,6 @@ fn vector16() !void { |
| 115 | 114 | |
| 116 | 115 | test "bitReverse vectors u16" { |
| 117 | 116 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 118 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 119 | 117 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 120 | 118 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 121 | 119 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | ... | @@ -134,7 +132,6 @@ fn vector24() !void { |
| 134 | 132 | |
| 135 | 133 | test "bitReverse vectors u24" { |
| 136 | 134 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 137 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 138 | 135 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 139 | 136 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 140 | 137 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
test/behavior/bugs/10147.zig-1| ... | ... | @@ -6,7 +6,6 @@ test "test calling @clz on both vector and scalar inputs" { |
| 6 | 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 7 | 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 8 | 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 10 | 9 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 11 | 10 | |
| 12 | 11 | var x: u32 = 0x1; |
test/behavior/byteswap.zig-3| ... | ... | @@ -62,7 +62,6 @@ fn vector8() !void { |
| 62 | 62 | |
| 63 | 63 | test "@byteSwap vectors u8" { |
| 64 | 64 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 65 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 66 | 65 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 67 | 66 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 68 | 67 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | ... | @@ -81,7 +80,6 @@ fn vector16() !void { |
| 81 | 80 | |
| 82 | 81 | test "@byteSwap vectors u16" { |
| 83 | 82 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 84 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 85 | 83 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 86 | 84 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 87 | 85 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | ... | @@ -100,7 +98,6 @@ fn vector24() !void { |
| 100 | 98 | |
| 101 | 99 | test "@byteSwap vectors u24" { |
| 102 | 100 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 103 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 104 | 101 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 105 | 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 106 | 103 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
test/behavior/cast.zig-1| ... | ... | @@ -598,7 +598,6 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" { |
| 598 | 598 | |
| 599 | 599 | test "vector casts" { |
| 600 | 600 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 601 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 602 | 601 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 603 | 602 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 604 | 603 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/floatop.zig-12| ... | ... | @@ -141,7 +141,6 @@ fn testSqrt() !void { |
| 141 | 141 | |
| 142 | 142 | test "@sqrt with vectors" { |
| 143 | 143 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 144 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 145 | 144 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 146 | 145 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 147 | 146 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -234,7 +233,6 @@ fn testSin() !void { |
| 234 | 233 | |
| 235 | 234 | test "@sin with vectors" { |
| 236 | 235 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 237 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 238 | 236 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 239 | 237 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 240 | 238 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -275,7 +273,6 @@ fn testCos() !void { |
| 275 | 273 | |
| 276 | 274 | test "@cos with vectors" { |
| 277 | 275 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 278 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 279 | 276 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 280 | 277 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 281 | 278 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -315,7 +312,6 @@ fn testExp() !void { |
| 315 | 312 | |
| 316 | 313 | test "@exp with vectors" { |
| 317 | 314 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 318 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 319 | 315 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 320 | 316 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 321 | 317 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -355,7 +351,6 @@ fn testExp2() !void { |
| 355 | 351 | |
| 356 | 352 | test "@exp2" { |
| 357 | 353 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 358 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 359 | 354 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 360 | 355 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 361 | 356 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -409,7 +404,6 @@ test "@log with @vectors" { |
| 409 | 404 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 410 | 405 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 411 | 406 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 412 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 413 | 407 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 414 | 408 | |
| 415 | 409 | { |
| ... | ... | @@ -447,7 +441,6 @@ test "@log2 with vectors" { |
| 447 | 441 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 448 | 442 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 449 | 443 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 450 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 451 | 444 | // https://github.com/ziglang/zig/issues/13681 |
| 452 | 445 | if (builtin.zig_backend == .stage2_llvm and |
| 453 | 446 | builtin.cpu.arch == .aarch64 and |
| ... | ... | @@ -491,7 +484,6 @@ test "@log10 with vectors" { |
| 491 | 484 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 492 | 485 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 493 | 486 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 494 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 495 | 487 | |
| 496 | 488 | comptime try testLog10WithVectors(); |
| 497 | 489 | try testLog10WithVectors(); |
| ... | ... | @@ -537,7 +529,6 @@ fn testFabs() !void { |
| 537 | 529 | |
| 538 | 530 | test "@fabs with vectors" { |
| 539 | 531 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 540 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 541 | 532 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 542 | 533 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 543 | 534 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -660,7 +651,6 @@ fn testFloor() !void { |
| 660 | 651 | |
| 661 | 652 | test "@floor with vectors" { |
| 662 | 653 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 663 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 664 | 654 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 665 | 655 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 666 | 656 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -754,7 +744,6 @@ fn testCeil() !void { |
| 754 | 744 | |
| 755 | 745 | test "@ceil with vectors" { |
| 756 | 746 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 757 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 758 | 747 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 759 | 748 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 760 | 749 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -848,7 +837,6 @@ fn testTrunc() !void { |
| 848 | 837 | |
| 849 | 838 | test "@trunc with vectors" { |
| 850 | 839 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 851 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 852 | 840 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 853 | 841 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 854 | 842 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/math.zig+6-3| ... | ... | @@ -100,7 +100,6 @@ test "@clz vectors" { |
| 100 | 100 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 101 | 101 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 102 | 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 103 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 104 | 103 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 105 | 104 | |
| 106 | 105 | try testClzVectors(); |
| ... | ... | @@ -163,7 +162,6 @@ test "@ctz vectors" { |
| 163 | 162 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 164 | 163 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 165 | 164 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 166 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 167 | 165 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 168 | 166 | |
| 169 | 167 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) { |
| ... | ... | @@ -1526,7 +1524,6 @@ fn testNanEqNan(comptime F: type) !void { |
| 1526 | 1524 | } |
| 1527 | 1525 | |
| 1528 | 1526 | test "vector comparison" { |
| 1529 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1530 | 1527 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1531 | 1528 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1532 | 1529 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1563,6 +1560,12 @@ test "signed zeros are represented properly" { |
| 1563 | 1560 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1564 | 1561 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1565 | 1562 | |
| 1563 | if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and | |
| 1564 | builtin.zig_backend == .stage2_c) | |
| 1565 | { | |
| 1566 | return error.SkipZigTest; | |
| 1567 | } | |
| 1568 | ||
| 1566 | 1569 | const S = struct { |
| 1567 | 1570 | fn doTheTest() !void { |
| 1568 | 1571 | try testOne(f16); |
test/behavior/maximum_minimum.zig-2| ... | ... | @@ -25,7 +25,6 @@ test "@max" { |
| 25 | 25 | test "@max on vectors" { |
| 26 | 26 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 27 | 27 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 28 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 29 | 28 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 30 | 29 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 31 | 30 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -75,7 +74,6 @@ test "@min for vectors" { |
| 75 | 74 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 76 | 75 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 77 | 76 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 78 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 79 | 77 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 80 | 78 | |
| 81 | 79 | const S = struct { |
test/behavior/muladd.zig+7-5| ... | ... | @@ -100,7 +100,6 @@ fn vector16() !void { |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | test "vector f16" { |
| 103 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 104 | 103 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 105 | 104 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 106 | 105 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -124,7 +123,6 @@ fn vector32() !void { |
| 124 | 123 | } |
| 125 | 124 | |
| 126 | 125 | test "vector f32" { |
| 127 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 128 | 126 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 129 | 127 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 130 | 128 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -148,7 +146,6 @@ fn vector64() !void { |
| 148 | 146 | } |
| 149 | 147 | |
| 150 | 148 | test "vector f64" { |
| 151 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 152 | 149 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 153 | 150 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 154 | 151 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -171,7 +168,6 @@ fn vector80() !void { |
| 171 | 168 | } |
| 172 | 169 | |
| 173 | 170 | test "vector f80" { |
| 174 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 175 | 171 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 176 | 172 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 177 | 173 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -195,13 +191,19 @@ fn vector128() !void { |
| 195 | 191 | } |
| 196 | 192 | |
| 197 | 193 | test "vector f128" { |
| 198 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 199 | 194 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 200 | 195 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 201 | 196 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 202 | 197 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 203 | 198 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 204 | 199 | |
| 200 | if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and | |
| 201 | builtin.zig_backend == .stage2_c) | |
| 202 | { | |
| 203 | // https://github.com/ziglang/zig/issues/13876 | |
| 204 | return error.SkipZigTest; | |
| 205 | } | |
| 206 | ||
| 205 | 207 | comptime try vector128(); |
| 206 | 208 | try vector128(); |
| 207 | 209 | } |
test/behavior/popcount.zig-1| ... | ... | @@ -67,7 +67,6 @@ fn testPopCountIntegers() !void { |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | test "@popCount vectors" { |
| 70 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 71 | 70 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 72 | 71 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 73 | 72 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/select.zig-2| ... | ... | @@ -4,7 +4,6 @@ const mem = std.mem; |
| 4 | 4 | const expect = std.testing.expect; |
| 5 | 5 | |
| 6 | 6 | test "@select vectors" { |
| 7 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 8 | 7 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 9 | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 10 | 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -33,7 +32,6 @@ fn selectVectors() !void { |
| 33 | 32 | } |
| 34 | 33 | |
| 35 | 34 | test "@select arrays" { |
| 36 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 37 | 35 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 38 | 36 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 39 | 37 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/shuffle.zig+1-4| ... | ... | @@ -8,7 +8,6 @@ test "@shuffle int" { |
| 8 | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 9 | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 10 | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 12 | 11 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 13 | 12 | |
| 14 | 13 | const S = struct { |
| ... | ... | @@ -50,7 +49,6 @@ test "@shuffle bool 1" { |
| 50 | 49 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 51 | 50 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 52 | 51 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 53 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 54 | 52 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 55 | 53 | |
| 56 | 54 | const S = struct { |
| ... | ... | @@ -71,7 +69,6 @@ test "@shuffle bool 2" { |
| 71 | 69 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 72 | 70 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 73 | 71 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 74 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 75 | 72 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 76 | 73 | |
| 77 | 74 | if (builtin.zig_backend == .stage2_llvm) { |
| ... | ... | @@ -83,7 +80,7 @@ test "@shuffle bool 2" { |
| 83 | 80 | fn doTheTest() !void { |
| 84 | 81 | var x: @Vector(3, bool) = [3]bool{ false, true, false }; |
| 85 | 82 | var v: @Vector(2, bool) = [2]bool{ true, false }; |
| 86 | const mask: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; | |
| 83 | const mask = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; | |
| 87 | 84 | var res = @shuffle(bool, x, v, mask); |
| 88 | 85 | try expect(mem.eql(bool, &@as([4]bool, res), &[4]bool{ false, false, true, false })); |
| 89 | 86 | } |
test/behavior/truncate.zig-1| ... | ... | @@ -60,7 +60,6 @@ test "truncate on comptime integer" { |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | test "truncate on vectors" { |
| 63 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 64 | 63 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 65 | 64 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 66 | 65 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
test/behavior/vector.zig+17-31| ... | ... | @@ -25,7 +25,6 @@ test "implicit cast vector to array - bool" { |
| 25 | 25 | |
| 26 | 26 | test "vector wrap operators" { |
| 27 | 27 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 28 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 29 | 28 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 30 | 29 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 31 | 30 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -48,7 +47,6 @@ test "vector wrap operators" { |
| 48 | 47 | |
| 49 | 48 | test "vector bin compares with mem.eql" { |
| 50 | 49 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 52 | 50 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 53 | 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 54 | 52 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -93,12 +91,18 @@ test "vector int operators" { |
| 93 | 91 | |
| 94 | 92 | test "vector float operators" { |
| 95 | 93 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 96 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 97 | 94 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 98 | 95 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 99 | 96 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 100 | 97 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 101 | 98 | |
| 99 | if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64 and | |
| 100 | builtin.zig_backend == .stage2_c) | |
| 101 | { | |
| 102 | // https://github.com/ziglang/zig/issues/13876 | |
| 103 | return error.SkipZigTest; | |
| 104 | } | |
| 105 | ||
| 102 | 106 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| { |
| 103 | 107 | const S = struct { |
| 104 | 108 | fn doTheTest() !void { |
| ... | ... | @@ -117,7 +121,6 @@ test "vector float operators" { |
| 117 | 121 | |
| 118 | 122 | test "vector bit operators" { |
| 119 | 123 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 120 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 121 | 124 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 122 | 125 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 123 | 126 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -237,7 +240,6 @@ test "vector casts of sizes not divisible by 8" { |
| 237 | 240 | } |
| 238 | 241 | |
| 239 | 242 | test "vector @splat" { |
| 240 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 241 | 243 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 242 | 244 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 243 | 245 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -403,7 +405,6 @@ test "initialize vector which is a struct field" { |
| 403 | 405 | |
| 404 | 406 | test "vector comparison operators" { |
| 405 | 407 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 406 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 407 | 408 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 408 | 409 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 409 | 410 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -444,7 +445,6 @@ test "vector comparison operators" { |
| 444 | 445 | |
| 445 | 446 | test "vector division operators" { |
| 446 | 447 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 447 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 448 | 448 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 449 | 449 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 450 | 450 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -527,7 +527,6 @@ test "vector division operators" { |
| 527 | 527 | |
| 528 | 528 | test "vector bitwise not operator" { |
| 529 | 529 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 530 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 531 | 530 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 532 | 531 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 533 | 532 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -559,7 +558,6 @@ test "vector bitwise not operator" { |
| 559 | 558 | |
| 560 | 559 | test "vector shift operators" { |
| 561 | 560 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 562 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 563 | 561 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 564 | 562 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 565 | 563 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -653,7 +651,6 @@ test "vector shift operators" { |
| 653 | 651 | |
| 654 | 652 | test "vector reduce operation" { |
| 655 | 653 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 656 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 657 | 654 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 658 | 655 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 659 | 656 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -709,7 +706,7 @@ test "vector reduce operation" { |
| 709 | 706 | |
| 710 | 707 | // LLVM 11 ERROR: Cannot select type |
| 711 | 708 | // https://github.com/ziglang/zig/issues/7138 |
| 712 | if (builtin.target.cpu.arch != .aarch64) { | |
| 709 | if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) { | |
| 713 | 710 | try testReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386)); |
| 714 | 711 | try testReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9)); |
| 715 | 712 | } |
| ... | ... | @@ -727,7 +724,7 @@ test "vector reduce operation" { |
| 727 | 724 | |
| 728 | 725 | // LLVM 11 ERROR: Cannot select type |
| 729 | 726 | // https://github.com/ziglang/zig/issues/7138 |
| 730 | if (builtin.target.cpu.arch != .aarch64) { | |
| 727 | if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) { | |
| 731 | 728 | try testReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567)); |
| 732 | 729 | try testReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999)); |
| 733 | 730 | } |
| ... | ... | @@ -775,14 +772,14 @@ test "vector reduce operation" { |
| 775 | 772 | |
| 776 | 773 | // LLVM 11 ERROR: Cannot select type |
| 777 | 774 | // https://github.com/ziglang/zig/issues/7138 |
| 778 | if (false) { | |
| 779 | try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 780 | try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 781 | try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 782 | ||
| 783 | try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 784 | try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 785 | try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 775 | if (builtin.zig_backend != .stage2_llvm) { | |
| 776 | try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9)); | |
| 777 | try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9)); | |
| 778 | try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9)); | |
| 779 | ||
| 780 | try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0)); | |
| 781 | try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0)); | |
| 782 | try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0)); | |
| 786 | 783 | } |
| 787 | 784 | |
| 788 | 785 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); |
| ... | ... | @@ -813,7 +810,6 @@ test "vector @reduce comptime" { |
| 813 | 810 | |
| 814 | 811 | test "mask parameter of @shuffle is comptime scope" { |
| 815 | 812 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 816 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 817 | 813 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 818 | 814 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 819 | 815 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -833,7 +829,6 @@ test "mask parameter of @shuffle is comptime scope" { |
| 833 | 829 | |
| 834 | 830 | test "saturating add" { |
| 835 | 831 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 836 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 837 | 832 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 838 | 833 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 839 | 834 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -865,7 +860,6 @@ test "saturating add" { |
| 865 | 860 | |
| 866 | 861 | test "saturating subtraction" { |
| 867 | 862 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 868 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 869 | 863 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 870 | 864 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 871 | 865 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -888,7 +882,6 @@ test "saturating subtraction" { |
| 888 | 882 | |
| 889 | 883 | test "saturating multiplication" { |
| 890 | 884 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 891 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 892 | 885 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 893 | 886 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 894 | 887 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -915,7 +908,6 @@ test "saturating multiplication" { |
| 915 | 908 | |
| 916 | 909 | test "saturating shift-left" { |
| 917 | 910 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 918 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 919 | 911 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 920 | 912 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 921 | 913 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1049,7 +1041,6 @@ test "@mulWithOverflow" { |
| 1049 | 1041 | } |
| 1050 | 1042 | |
| 1051 | 1043 | test "@shlWithOverflow" { |
| 1052 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1053 | 1044 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1054 | 1045 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1055 | 1046 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1131,7 +1122,6 @@ test "byte vector initialized in inline function" { |
| 1131 | 1122 | } |
| 1132 | 1123 | |
| 1133 | 1124 | test "byte vector initialized in inline function" { |
| 1134 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1135 | 1125 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1136 | 1126 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1137 | 1127 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1204,7 +1194,6 @@ test "zero multiplicand" { |
| 1204 | 1194 | |
| 1205 | 1195 | test "@intCast to u0" { |
| 1206 | 1196 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1207 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1208 | 1197 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1209 | 1198 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1210 | 1199 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1228,7 +1217,6 @@ test "modRem with zero divisor" { |
| 1228 | 1217 | |
| 1229 | 1218 | test "array operands to shuffle are coerced to vectors" { |
| 1230 | 1219 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1231 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1232 | 1220 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1233 | 1221 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1234 | 1222 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1247,7 +1235,6 @@ test "load packed vector element" { |
| 1247 | 1235 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1248 | 1236 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1249 | 1237 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1250 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1251 | 1238 | |
| 1252 | 1239 | var x: @Vector(2, u15) = .{ 1, 4 }; |
| 1253 | 1240 | try expect((&x[0]).* == 1); |
| ... | ... | @@ -1260,7 +1247,6 @@ test "store packed vector element" { |
| 1260 | 1247 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1261 | 1248 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1262 | 1249 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1263 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1264 | 1250 | |
| 1265 | 1251 | var v = @Vector(4, u1){ 1, 1, 1, 1 }; |
| 1266 | 1252 | try expectEqual(@Vector(4, u1){ 1, 1, 1, 1 }, v); |