| author | |
| committer | |
| log | c478c7609e4529267d1ce030577777e836ffc10b |
| tree | e7973c148c363ba3957015597b585e7610e2aeb1 |
| parent | b2e9c0d0ff1dc6799fe3b5fdbecd53af176f37b7 |
Also, bigint add and sub which is all I was actually trying to do.11 files changed, 809 insertions(+), 479 deletions(-)
lib/zig.h+440-220| ... | ... | @@ -612,12 +612,6 @@ static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 612 | 612 | #endif |
| 613 | 613 | } |
| 614 | 614 | |
| 615 | static inline void zig_vaddo_u32(uint8_t *ov, uint32_t *res, int n, | |
| 616 | const uint32_t *lhs, const uint32_t *rhs, uint8_t bits) | |
| 617 | { | |
| 618 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u32(&res[i], lhs[i], rhs[i], bits); | |
| 619 | } | |
| 620 | ||
| 621 | 615 | zig_extern int32_t __addosi4(int32_t lhs, int32_t rhs, int *overflow); |
| 622 | 616 | static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 623 | 617 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -632,12 +626,6 @@ static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 632 | 626 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 633 | 627 | } |
| 634 | 628 | |
| 635 | static inline void zig_vaddo_i32(uint8_t *ov, int32_t *res, int n, | |
| 636 | const int32_t *lhs, const int32_t *rhs, uint8_t bits) | |
| 637 | { | |
| 638 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i32(&res[i], lhs[i], rhs[i], bits); | |
| 639 | } | |
| 640 | ||
| 641 | 629 | static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 642 | 630 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 643 | 631 | uint64_t full_res; |
| ... | ... | @@ -650,12 +638,6 @@ static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 650 | 638 | #endif |
| 651 | 639 | } |
| 652 | 640 | |
| 653 | static inline void zig_vaddo_u64(uint8_t *ov, uint64_t *res, int n, | |
| 654 | const uint64_t *lhs, const uint64_t *rhs, uint8_t bits) | |
| 655 | { | |
| 656 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u64(&res[i], lhs[i], rhs[i], bits); | |
| 657 | } | |
| 658 | ||
| 659 | 641 | zig_extern int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow); |
| 660 | 642 | static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 661 | 643 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -670,12 +652,6 @@ static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 670 | 652 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 671 | 653 | } |
| 672 | 654 | |
| 673 | static inline void zig_vaddo_i64(uint8_t *ov, int64_t *res, int n, | |
| 674 | const int64_t *lhs, const int64_t *rhs, uint8_t bits) | |
| 675 | { | |
| 676 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i64(&res[i], lhs[i], rhs[i], bits); | |
| 677 | } | |
| 678 | ||
| 679 | 655 | static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 680 | 656 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 681 | 657 | uint8_t full_res; |
| ... | ... | @@ -690,12 +666,6 @@ static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 690 | 666 | #endif |
| 691 | 667 | } |
| 692 | 668 | |
| 693 | static inline void zig_vaddo_u8(uint8_t *ov, uint8_t *res, int n, | |
| 694 | const uint8_t *lhs, const uint8_t *rhs, uint8_t bits) | |
| 695 | { | |
| 696 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u8(&res[i], lhs[i], rhs[i], bits); | |
| 697 | } | |
| 698 | ||
| 699 | 669 | static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) { |
| 700 | 670 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 701 | 671 | int8_t full_res; |
| ... | ... | @@ -710,12 +680,6 @@ static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 710 | 680 | #endif |
| 711 | 681 | } |
| 712 | 682 | |
| 713 | static inline void zig_vaddo_i8(uint8_t *ov, int8_t *res, int n, | |
| 714 | const int8_t *lhs, const int8_t *rhs, uint8_t bits) | |
| 715 | { | |
| 716 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i8(&res[i], lhs[i], rhs[i], bits); | |
| 717 | } | |
| 718 | ||
| 719 | 683 | static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) { |
| 720 | 684 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 721 | 685 | uint16_t full_res; |
| ... | ... | @@ -730,12 +694,6 @@ static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 730 | 694 | #endif |
| 731 | 695 | } |
| 732 | 696 | |
| 733 | static inline void zig_vaddo_u16(uint8_t *ov, uint16_t *res, int n, | |
| 734 | const uint16_t *lhs, const uint16_t *rhs, uint8_t bits) | |
| 735 | { | |
| 736 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_u16(&res[i], lhs[i], rhs[i], bits); | |
| 737 | } | |
| 738 | ||
| 739 | 697 | static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) { |
| 740 | 698 | #if zig_has_builtin(add_overflow) || defined(zig_gnuc) |
| 741 | 699 | int16_t full_res; |
| ... | ... | @@ -750,12 +708,6 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 750 | 708 | #endif |
| 751 | 709 | } |
| 752 | 710 | |
| 753 | static inline void zig_vaddo_i16(uint8_t *ov, int16_t *res, int n, | |
| 754 | const int16_t *lhs, const int16_t *rhs, uint8_t bits) | |
| 755 | { | |
| 756 | for (int i = 0; i < n; ++i) ov[i] = zig_addo_i16(&res[i], lhs[i], rhs[i], bits); | |
| 757 | } | |
| 758 | ||
| 759 | 711 | static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 760 | 712 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 761 | 713 | uint32_t full_res; |
| ... | ... | @@ -768,12 +720,6 @@ static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 768 | 720 | #endif |
| 769 | 721 | } |
| 770 | 722 | |
| 771 | static inline void zig_vsubo_u32(uint8_t *ov, uint32_t *res, int n, | |
| 772 | const uint32_t *lhs, const uint32_t *rhs, uint8_t bits) | |
| 773 | { | |
| 774 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u32(&res[i], lhs[i], rhs[i], bits); | |
| 775 | } | |
| 776 | ||
| 777 | 723 | zig_extern int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow); |
| 778 | 724 | static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 779 | 725 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -788,12 +734,6 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 788 | 734 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 789 | 735 | } |
| 790 | 736 | |
| 791 | static inline void zig_vsubo_i32(uint8_t *ov, int32_t *res, int n, | |
| 792 | const int32_t *lhs, const int32_t *rhs, uint8_t bits) | |
| 793 | { | |
| 794 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i32(&res[i], lhs[i], rhs[i], bits); | |
| 795 | } | |
| 796 | ||
| 797 | 737 | static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 798 | 738 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 799 | 739 | uint64_t full_res; |
| ... | ... | @@ -806,12 +746,6 @@ static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 806 | 746 | #endif |
| 807 | 747 | } |
| 808 | 748 | |
| 809 | static inline void zig_vsubo_u64(uint8_t *ov, uint64_t *res, int n, | |
| 810 | const uint64_t *lhs, const uint64_t *rhs, uint8_t bits) | |
| 811 | { | |
| 812 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u64(&res[i], lhs[i], rhs[i], bits); | |
| 813 | } | |
| 814 | ||
| 815 | 749 | zig_extern int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow); |
| 816 | 750 | static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 817 | 751 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -826,12 +760,6 @@ static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 826 | 760 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 827 | 761 | } |
| 828 | 762 | |
| 829 | static inline void zig_vsubo_i64(uint8_t *ov, int64_t *res, int n, | |
| 830 | const int64_t *lhs, const int64_t *rhs, uint8_t bits) | |
| 831 | { | |
| 832 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i64(&res[i], lhs[i], rhs[i], bits); | |
| 833 | } | |
| 834 | ||
| 835 | 763 | static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 836 | 764 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 837 | 765 | uint8_t full_res; |
| ... | ... | @@ -846,12 +774,6 @@ static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 846 | 774 | #endif |
| 847 | 775 | } |
| 848 | 776 | |
| 849 | static inline void zig_vsubo_u8(uint8_t *ov, uint8_t *res, int n, | |
| 850 | const uint8_t *lhs, const uint8_t *rhs, uint8_t bits) | |
| 851 | { | |
| 852 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u8(&res[i], lhs[i], rhs[i], bits); | |
| 853 | } | |
| 854 | ||
| 855 | 777 | static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) { |
| 856 | 778 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 857 | 779 | int8_t full_res; |
| ... | ... | @@ -866,13 +788,6 @@ static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 866 | 788 | #endif |
| 867 | 789 | } |
| 868 | 790 | |
| 869 | static inline void zig_vsubo_i8(uint8_t *ov, int8_t *res, int n, | |
| 870 | const int8_t *lhs, const int8_t *rhs, uint8_t bits) | |
| 871 | { | |
| 872 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i8(&res[i], lhs[i], rhs[i], bits); | |
| 873 | } | |
| 874 | ||
| 875 | ||
| 876 | 791 | static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) { |
| 877 | 792 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 878 | 793 | uint16_t full_res; |
| ... | ... | @@ -887,13 +802,6 @@ static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 887 | 802 | #endif |
| 888 | 803 | } |
| 889 | 804 | |
| 890 | static inline void zig_vsubo_u16(uint8_t *ov, uint16_t *res, int n, | |
| 891 | const uint16_t *lhs, const uint16_t *rhs, uint8_t bits) | |
| 892 | { | |
| 893 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_u16(&res[i], lhs[i], rhs[i], bits); | |
| 894 | } | |
| 895 | ||
| 896 | ||
| 897 | 805 | static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) { |
| 898 | 806 | #if zig_has_builtin(sub_overflow) || defined(zig_gnuc) |
| 899 | 807 | int16_t full_res; |
| ... | ... | @@ -908,12 +816,6 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 908 | 816 | #endif |
| 909 | 817 | } |
| 910 | 818 | |
| 911 | static inline void zig_vsubo_i16(uint8_t *ov, int16_t *res, int n, | |
| 912 | const int16_t *lhs, const int16_t *rhs, uint8_t bits) | |
| 913 | { | |
| 914 | for (int i = 0; i < n; ++i) ov[i] = zig_subo_i16(&res[i], lhs[i], rhs[i], bits); | |
| 915 | } | |
| 916 | ||
| 917 | 819 | static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { |
| 918 | 820 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 919 | 821 | uint32_t full_res; |
| ... | ... | @@ -926,12 +828,6 @@ static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8 |
| 926 | 828 | #endif |
| 927 | 829 | } |
| 928 | 830 | |
| 929 | static inline void zig_vmulo_u32(uint8_t *ov, uint32_t *res, int n, | |
| 930 | const uint32_t *lhs, const uint32_t *rhs, uint8_t bits) | |
| 931 | { | |
| 932 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u32(&res[i], lhs[i], rhs[i], bits); | |
| 933 | } | |
| 934 | ||
| 935 | 831 | zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow); |
| 936 | 832 | static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) { |
| 937 | 833 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -946,12 +842,6 @@ static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t |
| 946 | 842 | return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); |
| 947 | 843 | } |
| 948 | 844 | |
| 949 | static inline void zig_vmulo_i32(uint8_t *ov, int32_t *res, int n, | |
| 950 | const int32_t *lhs, const int32_t *rhs, uint8_t bits) | |
| 951 | { | |
| 952 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i32(&res[i], lhs[i], rhs[i], bits); | |
| 953 | } | |
| 954 | ||
| 955 | 845 | static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { |
| 956 | 846 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 957 | 847 | uint64_t full_res; |
| ... | ... | @@ -964,12 +854,6 @@ static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8 |
| 964 | 854 | #endif |
| 965 | 855 | } |
| 966 | 856 | |
| 967 | static inline void zig_vmulo_u64(uint8_t *ov, uint64_t *res, int n, | |
| 968 | const uint64_t *lhs, const uint64_t *rhs, uint8_t bits) | |
| 969 | { | |
| 970 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u64(&res[i], lhs[i], rhs[i], bits); | |
| 971 | } | |
| 972 | ||
| 973 | 857 | zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); |
| 974 | 858 | static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) { |
| 975 | 859 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| ... | ... | @@ -984,12 +868,6 @@ static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t |
| 984 | 868 | return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits); |
| 985 | 869 | } |
| 986 | 870 | |
| 987 | static inline void zig_vmulo_i64(uint8_t *ov, int64_t *res, int n, | |
| 988 | const int64_t *lhs, const int64_t *rhs, uint8_t bits) | |
| 989 | { | |
| 990 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i64(&res[i], lhs[i], rhs[i], bits); | |
| 991 | } | |
| 992 | ||
| 993 | 871 | static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) { |
| 994 | 872 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 995 | 873 | uint8_t full_res; |
| ... | ... | @@ -1004,12 +882,6 @@ static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t b |
| 1004 | 882 | #endif |
| 1005 | 883 | } |
| 1006 | 884 | |
| 1007 | static inline void zig_vmulo_u8(uint8_t *ov, uint8_t *res, int n, | |
| 1008 | const uint8_t *lhs, const uint8_t *rhs, uint8_t bits) | |
| 1009 | { | |
| 1010 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u8(&res[i], lhs[i], rhs[i], bits); | |
| 1011 | } | |
| 1012 | ||
| 1013 | 885 | static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) { |
| 1014 | 886 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 1015 | 887 | int8_t full_res; |
| ... | ... | @@ -1024,12 +896,6 @@ static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits |
| 1024 | 896 | #endif |
| 1025 | 897 | } |
| 1026 | 898 | |
| 1027 | static inline void zig_vmulo_i8(uint8_t *ov, int8_t *res, int n, | |
| 1028 | const int8_t *lhs, const int8_t *rhs, uint8_t bits) | |
| 1029 | { | |
| 1030 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i8(&res[i], lhs[i], rhs[i], bits); | |
| 1031 | } | |
| 1032 | ||
| 1033 | 899 | static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) { |
| 1034 | 900 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 1035 | 901 | uint16_t full_res; |
| ... | ... | @@ -1044,12 +910,6 @@ static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8 |
| 1044 | 910 | #endif |
| 1045 | 911 | } |
| 1046 | 912 | |
| 1047 | static inline void zig_vmulo_u16(uint8_t *ov, uint16_t *res, int n, | |
| 1048 | const uint16_t *lhs, const uint16_t *rhs, uint8_t bits) | |
| 1049 | { | |
| 1050 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u16(&res[i], lhs[i], rhs[i], bits); | |
| 1051 | } | |
| 1052 | ||
| 1053 | 913 | static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) { |
| 1054 | 914 | #if zig_has_builtin(mul_overflow) || defined(zig_gnuc) |
| 1055 | 915 | int16_t full_res; |
| ... | ... | @@ -1064,12 +924,6 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t |
| 1064 | 924 | #endif |
| 1065 | 925 | } |
| 1066 | 926 | |
| 1067 | static inline void zig_vmulo_i16(uint8_t *ov, int16_t *res, int n, | |
| 1068 | const int16_t *lhs, const int16_t *rhs, uint8_t bits) | |
| 1069 | { | |
| 1070 | for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i16(&res[i], lhs[i], rhs[i], bits); | |
| 1071 | } | |
| 1072 | ||
| 1073 | 927 | #define zig_int_builtins(w) \ |
| 1074 | 928 | static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ |
| 1075 | 929 | *res = zig_shlw_u##w(lhs, rhs, bits); \ |
| ... | ... | @@ -2090,6 +1944,446 @@ static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_sign |
| 2090 | 1944 | return 0; |
| 2091 | 1945 | } |
| 2092 | 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 | ||
| 2093 | 2387 | static inline uint16_t zig_clz_big(const void *val, bool is_signed, uint16_t bits) { |
| 2094 | 2388 | const uint8_t *val_bytes = val; |
| 2095 | 2389 | uint16_t byte_offset = 0; |
| ... | ... | @@ -3092,80 +3386,6 @@ zig_msvc_atomics_128op(u128, max) |
| 3092 | 3386 | |
| 3093 | 3387 | #endif /* _MSC_VER && (_M_IX86 || _M_X64) */ |
| 3094 | 3388 | |
| 3095 | /* ============================= Vector Support ============================= */ | |
| 3096 | ||
| 3097 | #define zig_cmp_vec(operation, operator) \ | |
| 3098 | static inline void zig_##operation##_vec(bool *result, const void *lhs, const void *rhs, uint32_t len, bool is_signed, uint16_t elem_bits) { \ | |
| 3099 | uint32_t index = 0; \ | |
| 3100 | const uint8_t *lhs_ptr = lhs; \ | |
| 3101 | const uint8_t *rhs_ptr = rhs; \ | |
| 3102 | uint16_t elem_bytes = zig_int_bytes(elem_bits); \ | |
| 3103 | \ | |
| 3104 | while (index < len) { \ | |
| 3105 | result[index] = zig_cmp_big(lhs_ptr, rhs_ptr, is_signed, elem_bits) operator 0; \ | |
| 3106 | lhs_ptr += elem_bytes; \ | |
| 3107 | rhs_ptr += elem_bytes; \ | |
| 3108 | index += 1; \ | |
| 3109 | } \ | |
| 3110 | } | |
| 3111 | zig_cmp_vec(eq, ==) | |
| 3112 | zig_cmp_vec(ne, !=) | |
| 3113 | zig_cmp_vec(lt, < ) | |
| 3114 | zig_cmp_vec(le, <=) | |
| 3115 | zig_cmp_vec(gt, > ) | |
| 3116 | zig_cmp_vec(ge, >=) | |
| 3117 | ||
| 3118 | static inline void zig_clz_vec(void *result, const void *val, uint32_t len, bool is_signed, uint16_t elem_bits) { | |
| 3119 | uint32_t index = 0; | |
| 3120 | const uint8_t *val_ptr = val; | |
| 3121 | uint16_t elem_bytes = zig_int_bytes(elem_bits); | |
| 3122 | ||
| 3123 | while (index < len) { | |
| 3124 | uint16_t lz = zig_clz_big(val_ptr, is_signed, elem_bits); | |
| 3125 | if (elem_bits <= 128) { | |
| 3126 | ((uint8_t *)result)[index] = (uint8_t)lz; | |
| 3127 | } else { | |
| 3128 | ((uint16_t *)result)[index] = lz; | |
| 3129 | } | |
| 3130 | val_ptr += elem_bytes; | |
| 3131 | index += 1; | |
| 3132 | } | |
| 3133 | } | |
| 3134 | ||
| 3135 | static inline void zig_ctz_vec(void *result, const void *val, uint32_t len, bool is_signed, uint16_t elem_bits) { | |
| 3136 | uint32_t index = 0; | |
| 3137 | const uint8_t *val_ptr = val; | |
| 3138 | uint16_t elem_bytes = zig_int_bytes(elem_bits); | |
| 3139 | ||
| 3140 | while (index < len) { | |
| 3141 | uint16_t tz = zig_ctz_big(val_ptr, is_signed, elem_bits); | |
| 3142 | if (elem_bits <= 128) { | |
| 3143 | ((uint8_t *)result)[index] = (uint8_t)tz; | |
| 3144 | } else { | |
| 3145 | ((uint16_t *)result)[index] = tz; | |
| 3146 | } | |
| 3147 | val_ptr += elem_bytes; | |
| 3148 | index += 1; | |
| 3149 | } | |
| 3150 | } | |
| 3151 | ||
| 3152 | static inline void zig_popcount_vec(void *result, const void *val, uint32_t len, bool is_signed, uint16_t elem_bits) { | |
| 3153 | uint32_t index = 0; | |
| 3154 | const uint8_t *val_ptr = val; | |
| 3155 | uint16_t elem_bytes = zig_int_bytes(elem_bits); | |
| 3156 | ||
| 3157 | while (index < len) { | |
| 3158 | uint16_t pc = zig_popcount_big(val_ptr, is_signed, elem_bits); | |
| 3159 | if (elem_bits <= 128) { | |
| 3160 | ((uint8_t *)result)[index] = (uint8_t)pc; | |
| 3161 | } else { | |
| 3162 | ((uint16_t *)result)[index] = pc; | |
| 3163 | } | |
| 3164 | val_ptr += elem_bytes; | |
| 3165 | index += 1; | |
| 3166 | } | |
| 3167 | } | |
| 3168 | ||
| 3169 | 3389 | /* ======================== Special Case Intrinsics ========================= */ |
| 3170 | 3390 | |
| 3171 | 3391 | #if (_MSC_VER && _M_X64) || defined(__x86_64__) |
src/codegen/c.zig+357-209| ... | ... | @@ -444,8 +444,8 @@ pub const Function = struct { |
| 444 | 444 | return f.object.dg.renderType(w, t); |
| 445 | 445 | } |
| 446 | 446 | |
| 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); | |
| 447 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorizer, src_ty: Type, location: ValueRenderLocation) !void { | |
| 448 | return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); | |
| 449 | 449 | } |
| 450 | 450 | |
| 451 | 451 | fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) { |
| ... | ... | @@ -1593,6 +1593,7 @@ pub const DeclGen = struct { |
| 1593 | 1593 | c_value: struct { |
| 1594 | 1594 | f: *Function, |
| 1595 | 1595 | value: CValue, |
| 1596 | v: Vectorizer, | |
| 1596 | 1597 | }, |
| 1597 | 1598 | value: struct { |
| 1598 | 1599 | value: Value, |
| ... | ... | @@ -1602,6 +1603,7 @@ pub const DeclGen = struct { |
| 1602 | 1603 | switch (self.*) { |
| 1603 | 1604 | .c_value => |v| { |
| 1604 | 1605 | try v.f.writeCValue(w, v.value, location); |
| 1606 | try v.v.elem(v.f, w); | |
| 1605 | 1607 | }, |
| 1606 | 1608 | .value => |v| { |
| 1607 | 1609 | try dg.renderValue(w, value_ty, v.value, location); |
| ... | ... | @@ -1887,7 +1889,6 @@ pub const DeclGen = struct { |
| 1887 | 1889 | if (cty.isFloat()) cty.floatActiveBits(dg.module.getTarget()) else dg.byteSize(cty) * 8, |
| 1888 | 1890 | }), |
| 1889 | 1891 | .array => try writer.writeAll("big"), |
| 1890 | .vector => try writer.writeAll("vec"), | |
| 1891 | 1892 | } |
| 1892 | 1893 | } |
| 1893 | 1894 | |
| ... | ... | @@ -1895,34 +1896,19 @@ pub const DeclGen = struct { |
| 1895 | 1896 | switch (info) { |
| 1896 | 1897 | .none => {}, |
| 1897 | 1898 | .bits => { |
| 1898 | const cty = try dg.typeToCType(ty, .complete); | |
| 1899 | if (cty.castTag(.vector)) |pl| { | |
| 1900 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = pl.data.len }; | |
| 1901 | try writer.print(", {}", .{try dg.fmtIntLiteral( | |
| 1902 | Type.u32, | |
| 1903 | Value.initPayload(&len_pl.base), | |
| 1904 | .FunctionArgument, | |
| 1905 | )}); | |
| 1906 | } | |
| 1907 | ||
| 1908 | 1899 | const target = dg.module.getTarget(); |
| 1909 | const elem_ty = ty.shallowElemType(); | |
| 1910 | const elem_info = if (elem_ty.isAbiInt()) | |
| 1911 | elem_ty.intInfo(target) | |
| 1912 | else | |
| 1913 | std.builtin.Type.Int{ | |
| 1914 | .signedness = .unsigned, | |
| 1915 | .bits = @intCast(u16, elem_ty.bitSize(target)), | |
| 1916 | }; | |
| 1917 | switch (cty.tag()) { | |
| 1918 | else => {}, | |
| 1919 | .array, .vector => try writer.print(", {}", .{elem_info.signedness == .signed}), | |
| 1920 | } | |
| 1900 | const int_info = if (ty.isAbiInt()) ty.intInfo(target) else std.builtin.Type.Int{ | |
| 1901 | .signedness = .unsigned, | |
| 1902 | .bits = @intCast(u16, ty.bitSize(target)), | |
| 1903 | }; | |
| 1904 | ||
| 1905 | const cty = try dg.typeToCType(ty, .complete); | |
| 1906 | if (cty.tag() == .array) try writer.print(", {}", .{int_info.signedness == .signed}); | |
| 1921 | 1907 | |
| 1922 | var bits_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = elem_info.bits }; | |
| 1908 | var bits_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = int_info.bits }; | |
| 1923 | 1909 | try writer.print(", {}", .{try dg.fmtIntLiteral(switch (cty.tag()) { |
| 1924 | 1910 | else => Type.u8, |
| 1925 | .array, .vector => Type.u16, | |
| 1911 | .array => Type.u16, | |
| 1926 | 1912 | }, Value.initPayload(&bits_pl.base), .FunctionArgument)}); |
| 1927 | 1913 | }, |
| 1928 | 1914 | } |
| ... | ... | @@ -2786,10 +2772,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2786 | 2772 | .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none), |
| 2787 | 2773 | .rem => blk: { |
| 2788 | 2774 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2789 | const lhs_ty = f.air.typeOf(bin_op.lhs); | |
| 2775 | const lhs_scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(); | |
| 2790 | 2776 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), |
| 2791 | 2777 | // so we only check one. |
| 2792 | break :blk if (lhs_ty.isInt()) | |
| 2778 | break :blk if (lhs_scalar_ty.isInt()) | |
| 2793 | 2779 | try airBinOp(f, inst, "%", "rem", .none) |
| 2794 | 2780 | else |
| 2795 | 2781 | try airBinFloatOp(f, inst, "fmod"); |
| ... | ... | @@ -2833,10 +2819,10 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2833 | 2819 | |
| 2834 | 2820 | .slice => try airSlice(f, inst), |
| 2835 | 2821 | |
| 2836 | .cmp_gt => try airCmpOp(f, inst, .gt), | |
| 2837 | .cmp_gte => try airCmpOp(f, inst, .gte), | |
| 2838 | .cmp_lt => try airCmpOp(f, inst, .lt), | |
| 2839 | .cmp_lte => try airCmpOp(f, inst, .lte), | |
| 2822 | .cmp_gt => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .gt), | |
| 2823 | .cmp_gte => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .gte), | |
| 2824 | .cmp_lt => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .lt), | |
| 2825 | .cmp_lte => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .lte), | |
| 2840 | 2826 | |
| 2841 | 2827 | .cmp_eq => try airEquality(f, inst, .eq), |
| 2842 | 2828 | .cmp_neq => try airEquality(f, inst, .neq), |
| ... | ... | @@ -2844,7 +2830,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 2844 | 2830 | .cmp_vector => blk: { |
| 2845 | 2831 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 2846 | 2832 | const extra = f.air.extraData(Air.VectorCmp, ty_pl.payload).data; |
| 2847 | break :blk try airCmpBuiltinCall(f, inst, extra, extra.compareOperator(), .operator, .bits,); | |
| 2833 | break :blk try airCmpOp(f, inst, extra, extra.compareOperator()); | |
| 2848 | 2834 | }, |
| 2849 | 2835 | .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst), |
| 2850 | 2836 | |
| ... | ... | @@ -3294,7 +3280,10 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3294 | 3280 | |
| 3295 | 3281 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3296 | 3282 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3297 | const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data; | |
| 3283 | ||
| 3284 | const ptr_ty = f.air.typeOf(ty_op.operand); | |
| 3285 | const ptr_scalar_ty = ptr_ty.scalarType(); | |
| 3286 | const ptr_info = ptr_scalar_ty.ptrInfo().data; | |
| 3298 | 3287 | const src_ty = ptr_info.pointee_type; |
| 3299 | 3288 | |
| 3300 | 3289 | if (!src_ty.hasRuntimeBitsIgnoreComptime() or |
| ... | ... | @@ -3312,16 +3301,19 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3312 | 3301 | const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(target); |
| 3313 | 3302 | const is_array = lowersToArray(src_ty, target); |
| 3314 | 3303 | const need_memcpy = !is_aligned or is_array; |
| 3315 | const writer = f.object.writer(); | |
| 3316 | 3304 | |
| 3305 | const writer = f.object.writer(); | |
| 3317 | 3306 | const local = try f.allocLocal(inst, src_ty); |
| 3307 | const v = try Vectorizer.start(f, inst, writer, ptr_ty); | |
| 3318 | 3308 | |
| 3319 | 3309 | if (need_memcpy) { |
| 3320 | 3310 | try writer.writeAll("memcpy("); |
| 3321 | 3311 | if (!is_array) try writer.writeByte('&'); |
| 3322 | try f.writeCValue(writer, local, .FunctionArgument); | |
| 3312 | try f.writeCValue(writer, local, .Other); | |
| 3313 | try v.elem(f, writer); | |
| 3323 | 3314 | try writer.writeAll(", (const char *)"); |
| 3324 | 3315 | try f.writeCValue(writer, operand, .Other); |
| 3316 | try v.elem(f, writer); | |
| 3325 | 3317 | try writer.writeAll(", sizeof("); |
| 3326 | 3318 | try f.renderType(writer, src_ty); |
| 3327 | 3319 | try writer.writeAll("))"); |
| ... | ... | @@ -3351,6 +3343,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3351 | 3343 | const field_ty = Type.initPayload(&field_pl.base); |
| 3352 | 3344 | |
| 3353 | 3345 | try f.writeCValue(writer, local, .Other); |
| 3346 | try v.elem(f, writer); | |
| 3354 | 3347 | try writer.writeAll(" = ("); |
| 3355 | 3348 | try f.renderType(writer, src_ty); |
| 3356 | 3349 | try writer.writeAll(")zig_wrap_"); |
| ... | ... | @@ -3369,16 +3362,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3369 | 3362 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3370 | 3363 | try writer.writeByte('('); |
| 3371 | 3364 | try f.writeCValueDeref(writer, operand); |
| 3365 | try v.elem(f, writer); | |
| 3372 | 3366 | try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); |
| 3373 | 3367 | if (cant_cast) try writer.writeByte(')'); |
| 3374 | 3368 | try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits); |
| 3375 | 3369 | try writer.writeByte(')'); |
| 3376 | 3370 | } else { |
| 3377 | 3371 | try f.writeCValue(writer, local, .Other); |
| 3372 | try v.elem(f, writer); | |
| 3378 | 3373 | try writer.writeAll(" = "); |
| 3379 | 3374 | try f.writeCValueDeref(writer, operand); |
| 3375 | try v.elem(f, writer); | |
| 3380 | 3376 | } |
| 3381 | 3377 | try writer.writeAll(";\n"); |
| 3378 | try v.end(f, inst, writer); | |
| 3379 | ||
| 3382 | 3380 | return local; |
| 3383 | 3381 | } |
| 3384 | 3382 | |
| ... | ... | @@ -3444,15 +3442,22 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3444 | 3442 | |
| 3445 | 3443 | const operand = try f.resolveInst(ty_op.operand); |
| 3446 | 3444 | try reap(f, inst, &.{ty_op.operand}); |
| 3447 | const writer = f.object.writer(); | |
| 3445 | ||
| 3448 | 3446 | const inst_ty = f.air.typeOfIndex(inst); |
| 3449 | const local = try f.allocLocal(inst, inst_ty); | |
| 3447 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 3450 | 3448 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3449 | const scalar_ty = operand_ty.scalarType(); | |
| 3451 | 3450 | |
| 3451 | const writer = f.object.writer(); | |
| 3452 | const local = try f.allocLocal(inst, inst_ty); | |
| 3453 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3452 | 3454 | try f.writeCValue(writer, local, .Other); |
| 3455 | try v.elem(f, writer); | |
| 3453 | 3456 | try writer.writeAll(" = "); |
| 3454 | try f.renderIntCast(writer, inst_ty, operand, operand_ty, .Other); | |
| 3457 | try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other); | |
| 3455 | 3458 | try writer.writeAll(";\n"); |
| 3459 | try v.end(f, inst, writer); | |
| 3460 | ||
| 3456 | 3461 | return local; |
| 3457 | 3462 | } |
| 3458 | 3463 | |
| ... | ... | @@ -3578,7 +3583,10 @@ fn storeUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue { |
| 3578 | 3583 | fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3579 | 3584 | // *a = b; |
| 3580 | 3585 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3581 | const ptr_info = f.air.typeOf(bin_op.lhs).ptrInfo().data; | |
| 3586 | ||
| 3587 | const ptr_ty = f.air.typeOf(bin_op.lhs); | |
| 3588 | const ptr_scalar_ty = ptr_ty.scalarType(); | |
| 3589 | const ptr_info = ptr_scalar_ty.ptrInfo().data; | |
| 3582 | 3590 | if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) { |
| 3583 | 3591 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3584 | 3592 | return .none; |
| ... | ... | @@ -3601,11 +3609,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3601 | 3609 | ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(target); |
| 3602 | 3610 | const is_array = lowersToArray(ptr_info.pointee_type, target); |
| 3603 | 3611 | const need_memcpy = !is_aligned or is_array; |
| 3604 | const writer = f.object.writer(); | |
| 3605 | 3612 | |
| 3606 | 3613 | const src_val = try f.resolveInst(bin_op.rhs); |
| 3607 | 3614 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3608 | 3615 | |
| 3616 | const writer = f.object.writer(); | |
| 3617 | const v = try Vectorizer.start(f, inst, writer, ptr_ty); | |
| 3618 | ||
| 3609 | 3619 | if (need_memcpy) { |
| 3610 | 3620 | // For this memcpy to safely work we need the rhs to have the same |
| 3611 | 3621 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). |
| ... | ... | @@ -3626,9 +3636,11 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3626 | 3636 | |
| 3627 | 3637 | try writer.writeAll("memcpy((char *)"); |
| 3628 | 3638 | try f.writeCValue(writer, ptr_val, .FunctionArgument); |
| 3639 | try v.elem(f, writer); | |
| 3629 | 3640 | try writer.writeAll(", "); |
| 3630 | 3641 | if (!is_array) try writer.writeByte('&'); |
| 3631 | 3642 | try f.writeCValue(writer, array_src, .FunctionArgument); |
| 3643 | try v.elem(f, writer); | |
| 3632 | 3644 | try writer.writeAll(", sizeof("); |
| 3633 | 3645 | try f.renderType(writer, src_ty); |
| 3634 | 3646 | try writer.writeAll("))"); |
| ... | ... | @@ -3672,12 +3684,14 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3672 | 3684 | const mask_val = Value.initPayload(&mask_pl.base); |
| 3673 | 3685 | |
| 3674 | 3686 | try f.writeCValueDeref(writer, ptr_val); |
| 3687 | try v.elem(f, writer); | |
| 3675 | 3688 | try writer.writeAll(" = zig_or_"); |
| 3676 | 3689 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3677 | 3690 | try writer.writeAll("(zig_and_"); |
| 3678 | 3691 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3679 | 3692 | try writer.writeByte('('); |
| 3680 | 3693 | try f.writeCValueDeref(writer, ptr_val); |
| 3694 | try v.elem(f, writer); | |
| 3681 | 3695 | try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)}); |
| 3682 | 3696 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); |
| 3683 | 3697 | try writer.writeByte('('); |
| ... | ... | @@ -3699,14 +3713,19 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3699 | 3713 | try writer.writeByte(')'); |
| 3700 | 3714 | } |
| 3701 | 3715 | try f.writeCValue(writer, src_val, .Other); |
| 3716 | try v.elem(f, writer); | |
| 3702 | 3717 | if (cant_cast) try writer.writeByte(')'); |
| 3703 | 3718 | try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); |
| 3704 | 3719 | } else { |
| 3705 | 3720 | try f.writeCValueDeref(writer, ptr_val); |
| 3721 | try v.elem(f, writer); | |
| 3706 | 3722 | try writer.writeAll(" = "); |
| 3707 | 3723 | try f.writeCValue(writer, src_val, .Other); |
| 3724 | try v.elem(f, writer); | |
| 3708 | 3725 | } |
| 3709 | 3726 | try writer.writeAll(";\n"); |
| 3727 | try v.end(f, inst, writer); | |
| 3728 | ||
| 3710 | 3729 | return .none; |
| 3711 | 3730 | } |
| 3712 | 3731 | |
| ... | ... | @@ -3724,51 +3743,39 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: |
| 3724 | 3743 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3725 | 3744 | |
| 3726 | 3745 | const inst_ty = f.air.typeOfIndex(inst); |
| 3727 | const vector_ty = f.air.typeOf(bin_op.lhs); | |
| 3728 | const scalar_ty = vector_ty.scalarType(); | |
| 3729 | const w = f.object.writer(); | |
| 3746 | const operand_ty = f.air.typeOf(bin_op.lhs); | |
| 3747 | const scalar_ty = operand_ty.scalarType(); | |
| 3730 | 3748 | |
| 3749 | const w = f.object.writer(); | |
| 3731 | 3750 | const local = try f.allocLocal(inst, inst_ty); |
| 3732 | ||
| 3733 | switch (vector_ty.zigTypeTag()) { | |
| 3734 | .Vector => { | |
| 3735 | try w.writeAll("zig_v"); | |
| 3736 | try w.writeAll(operation); | |
| 3737 | try w.writeAll("o_"); | |
| 3738 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | |
| 3739 | try w.writeAll("("); | |
| 3740 | try f.writeCValueMember(w, local, .{ .field = 1 }); | |
| 3741 | try w.writeAll(", "); | |
| 3742 | try f.writeCValueMember(w, local, .{ .field = 0 }); | |
| 3743 | try w.print(", {d}, ", .{vector_ty.vectorLen()}); | |
| 3744 | }, | |
| 3745 | else => { | |
| 3746 | try f.writeCValueMember(w, local, .{ .field = 1 }); | |
| 3747 | try w.writeAll(" = zig_"); | |
| 3748 | try w.writeAll(operation); | |
| 3749 | try w.writeAll("o_"); | |
| 3750 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | |
| 3751 | try w.writeAll("(&"); | |
| 3752 | try f.writeCValueMember(w, local, .{ .field = 0 }); | |
| 3753 | try w.writeAll(", "); | |
| 3754 | }, | |
| 3755 | } | |
| 3756 | ||
| 3751 | const v = try Vectorizer.start(f, inst, w, operand_ty); | |
| 3752 | try f.writeCValueMember(w, local, .{ .field = 1 }); | |
| 3753 | try v.elem(f, w); | |
| 3754 | try w.writeAll(" = zig_"); | |
| 3755 | try w.writeAll(operation); | |
| 3756 | try w.writeAll("o_"); | |
| 3757 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | |
| 3758 | try w.writeAll("(&"); | |
| 3759 | try f.writeCValueMember(w, local, .{ .field = 0 }); | |
| 3760 | try v.elem(f, w); | |
| 3761 | try w.writeAll(", "); | |
| 3757 | 3762 | try f.writeCValue(w, lhs, .FunctionArgument); |
| 3763 | try v.elem(f, w); | |
| 3758 | 3764 | try w.writeAll(", "); |
| 3759 | 3765 | try f.writeCValue(w, rhs, .FunctionArgument); |
| 3766 | try v.elem(f, w); | |
| 3760 | 3767 | try f.object.dg.renderBuiltinInfo(w, scalar_ty, info); |
| 3761 | 3768 | try w.writeAll(");\n"); |
| 3769 | try v.end(f, inst, w); | |
| 3762 | 3770 | |
| 3763 | 3771 | return local; |
| 3764 | 3772 | } |
| 3765 | 3773 | |
| 3766 | 3774 | fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3767 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3768 | if (inst_ty.tag() != .bool) | |
| 3769 | return try airUnBuiltinCall(f, inst, "not", .bits); | |
| 3770 | ||
| 3771 | 3775 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3776 | const operand_ty = f.air.typeOf(ty_op.operand); | |
| 3777 | const scalar_ty = operand_ty.scalarType(); | |
| 3778 | if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits); | |
| 3772 | 3779 | |
| 3773 | 3780 | if (f.liveness.isUnused(inst)) { |
| 3774 | 3781 | try reap(f, inst, &.{ty_op.operand}); |
| ... | ... | @@ -3778,14 +3785,20 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3778 | 3785 | const op = try f.resolveInst(ty_op.operand); |
| 3779 | 3786 | try reap(f, inst, &.{ty_op.operand}); |
| 3780 | 3787 | |
| 3788 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3789 | ||
| 3781 | 3790 | const writer = f.object.writer(); |
| 3782 | 3791 | const local = try f.allocLocal(inst, inst_ty); |
| 3783 | ||
| 3792 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3784 | 3793 | try f.writeCValue(writer, local, .Other); |
| 3794 | try v.elem(f, writer); | |
| 3785 | 3795 | try writer.writeAll(" = "); |
| 3786 | 3796 | try writer.writeByte('!'); |
| 3787 | 3797 | try f.writeCValue(writer, op, .Other); |
| 3798 | try v.elem(f, writer); | |
| 3788 | 3799 | try writer.writeAll(";\n"); |
| 3800 | try v.end(f, inst, writer); | |
| 3801 | ||
| 3789 | 3802 | return local; |
| 3790 | 3803 | } |
| 3791 | 3804 | |
| ... | ... | @@ -3798,71 +3811,89 @@ fn airBinOp( |
| 3798 | 3811 | ) !CValue { |
| 3799 | 3812 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3800 | 3813 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 3814 | const scalar_ty = operand_ty.scalarType(); | |
| 3801 | 3815 | const target = f.object.dg.module.getTarget(); |
| 3802 | if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat()) | |
| 3816 | if ((scalar_ty.isInt() and scalar_ty.bitSize(target) > 64) or scalar_ty.isRuntimeFloat()) | |
| 3803 | 3817 | return try airBinBuiltinCall(f, inst, operation, info); |
| 3804 | 3818 | |
| 3819 | if (f.liveness.isUnused(inst)) { | |
| 3820 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 3821 | return .none; | |
| 3822 | } | |
| 3823 | ||
| 3805 | 3824 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3806 | 3825 | const rhs = try f.resolveInst(bin_op.rhs); |
| 3807 | ||
| 3808 | 3826 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3809 | 3827 | |
| 3810 | if (f.liveness.isUnused(inst)) return .none; | |
| 3811 | ||
| 3812 | 3828 | const inst_ty = f.air.typeOfIndex(inst); |
| 3813 | 3829 | |
| 3814 | 3830 | const writer = f.object.writer(); |
| 3815 | 3831 | const local = try f.allocLocal(inst, inst_ty); |
| 3832 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3816 | 3833 | try f.writeCValue(writer, local, .Other); |
| 3834 | try v.elem(f, writer); | |
| 3817 | 3835 | try writer.writeAll(" = "); |
| 3818 | 3836 | try f.writeCValue(writer, lhs, .Other); |
| 3837 | try v.elem(f, writer); | |
| 3819 | 3838 | try writer.writeByte(' '); |
| 3820 | 3839 | try writer.writeAll(operator); |
| 3821 | 3840 | try writer.writeByte(' '); |
| 3822 | 3841 | try f.writeCValue(writer, rhs, .Other); |
| 3842 | try v.elem(f, writer); | |
| 3823 | 3843 | try writer.writeAll(";\n"); |
| 3844 | try v.end(f, inst, writer); | |
| 3824 | 3845 | |
| 3825 | 3846 | return local; |
| 3826 | 3847 | } |
| 3827 | 3848 | |
| 3828 | fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: std.math.CompareOperator) !CValue { | |
| 3829 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | |
| 3830 | ||
| 3849 | fn airCmpOp( | |
| 3850 | f: *Function, | |
| 3851 | inst: Air.Inst.Index, | |
| 3852 | data: anytype, | |
| 3853 | operator: std.math.CompareOperator, | |
| 3854 | ) !CValue { | |
| 3831 | 3855 | if (f.liveness.isUnused(inst)) { |
| 3832 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 3856 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 3833 | 3857 | return .none; |
| 3834 | 3858 | } |
| 3835 | 3859 | |
| 3836 | const operand_ty = f.air.typeOf(bin_op.lhs); | |
| 3860 | const operand_ty = f.air.typeOf(data.lhs); | |
| 3861 | const scalar_ty = operand_ty.scalarType(); | |
| 3862 | ||
| 3837 | 3863 | const target = f.object.dg.module.getTarget(); |
| 3838 | const operand_bits = operand_ty.bitSize(target); | |
| 3839 | if (operand_ty.isInt() and operand_bits > 64) | |
| 3864 | const scalar_bits = scalar_ty.bitSize(target); | |
| 3865 | if (scalar_ty.isInt() and scalar_bits > 64) | |
| 3840 | 3866 | return airCmpBuiltinCall( |
| 3841 | 3867 | f, |
| 3842 | 3868 | inst, |
| 3843 | bin_op, | |
| 3869 | data, | |
| 3844 | 3870 | operator, |
| 3845 | 3871 | .cmp, |
| 3846 | if (operand_bits > 128) .bits else .none, | |
| 3872 | if (scalar_bits > 128) .bits else .none, | |
| 3847 | 3873 | ); |
| 3848 | if (operand_ty.isRuntimeFloat()) | |
| 3849 | return airCmpBuiltinCall(f, inst, bin_op, operator, .operator, .none); | |
| 3874 | if (scalar_ty.isRuntimeFloat()) | |
| 3875 | return airCmpBuiltinCall(f, inst, data, operator, .operator, .none); | |
| 3850 | 3876 | |
| 3851 | 3877 | const inst_ty = f.air.typeOfIndex(inst); |
| 3852 | const lhs = try f.resolveInst(bin_op.lhs); | |
| 3853 | const rhs = try f.resolveInst(bin_op.rhs); | |
| 3854 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | |
| 3878 | const lhs = try f.resolveInst(data.lhs); | |
| 3879 | const rhs = try f.resolveInst(data.rhs); | |
| 3880 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 3855 | 3881 | |
| 3856 | 3882 | const writer = f.object.writer(); |
| 3857 | 3883 | const local = try f.allocLocal(inst, inst_ty); |
| 3884 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 3858 | 3885 | try f.writeCValue(writer, local, .Other); |
| 3886 | try v.elem(f, writer); | |
| 3859 | 3887 | try writer.writeAll(" = "); |
| 3860 | 3888 | try f.writeCValue(writer, lhs, .Other); |
| 3889 | try v.elem(f, writer); | |
| 3861 | 3890 | try writer.writeByte(' '); |
| 3862 | 3891 | try writer.writeAll(compareOperatorC(operator)); |
| 3863 | 3892 | try writer.writeByte(' '); |
| 3864 | 3893 | try f.writeCValue(writer, rhs, .Other); |
| 3894 | try v.elem(f, writer); | |
| 3865 | 3895 | try writer.writeAll(";\n"); |
| 3896 | try v.end(f, inst, writer); | |
| 3866 | 3897 | |
| 3867 | 3898 | return local; |
| 3868 | 3899 | } |
| ... | ... | @@ -3974,11 +4005,14 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3974 | 4005 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 3975 | 4006 | |
| 3976 | 4007 | const inst_ty = f.air.typeOfIndex(inst); |
| 3977 | const elem_ty = inst_ty.elemType2(); | |
| 4008 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 4009 | const elem_ty = inst_scalar_ty.elemType2(); | |
| 3978 | 4010 | |
| 3979 | 4011 | const local = try f.allocLocal(inst, inst_ty); |
| 3980 | 4012 | const writer = f.object.writer(); |
| 4013 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 3981 | 4014 | try f.writeCValue(writer, local, .Other); |
| 4015 | try v.elem(f, writer); | |
| 3982 | 4016 | try writer.writeAll(" = "); |
| 3983 | 4017 | |
| 3984 | 4018 | if (elem_ty.hasRuntimeBitsIgnoreComptime()) { |
| ... | ... | @@ -3986,19 +4020,26 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3986 | 4020 | // results in a NULL pointer, or if LHS is NULL. The operation is only UB |
| 3987 | 4021 | // if the result is NULL and then dereferenced. |
| 3988 | 4022 | try writer.writeByte('('); |
| 3989 | try f.renderType(writer, inst_ty); | |
| 4023 | try f.renderType(writer, inst_scalar_ty); | |
| 3990 | 4024 | try writer.writeAll(")(((uintptr_t)"); |
| 3991 | 4025 | try f.writeCValue(writer, lhs, .Other); |
| 4026 | try v.elem(f, writer); | |
| 3992 | 4027 | try writer.writeAll(") "); |
| 3993 | 4028 | try writer.writeByte(operator); |
| 3994 | 4029 | try writer.writeAll(" ("); |
| 3995 | 4030 | try f.writeCValue(writer, rhs, .Other); |
| 4031 | try v.elem(f, writer); | |
| 3996 | 4032 | try writer.writeAll("*sizeof("); |
| 3997 | 4033 | try f.renderType(writer, elem_ty); |
| 3998 | 4034 | try writer.writeAll(")))"); |
| 3999 | } else try f.writeCValue(writer, lhs, .Initializer); | |
| 4035 | } else { | |
| 4036 | try f.writeCValue(writer, lhs, .Other); | |
| 4037 | try v.elem(f, writer); | |
| 4038 | } | |
| 4000 | 4039 | |
| 4001 | 4040 | try writer.writeAll(";\n"); |
| 4041 | try v.end(f, inst, writer); | |
| 4042 | ||
| 4002 | 4043 | return local; |
| 4003 | 4044 | } |
| 4004 | 4045 | |
| ... | ... | @@ -4011,10 +4052,12 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 4011 | 4052 | } |
| 4012 | 4053 | |
| 4013 | 4054 | const inst_ty = f.air.typeOfIndex(inst); |
| 4055 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 4056 | ||
| 4014 | 4057 | const target = f.object.dg.module.getTarget(); |
| 4015 | if (inst_ty.isInt() and inst_ty.bitSize(target) > 64) | |
| 4058 | if (inst_scalar_ty.isInt() and inst_scalar_ty.bitSize(target) > 64) | |
| 4016 | 4059 | return try airBinBuiltinCall(f, inst, operation[1..], .none); |
| 4017 | if (inst_ty.isRuntimeFloat()) | |
| 4060 | if (inst_scalar_ty.isRuntimeFloat()) | |
| 4018 | 4061 | return try airBinFloatOp(f, inst, operation); |
| 4019 | 4062 | |
| 4020 | 4063 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | ... | @@ -4023,19 +4066,26 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons |
| 4023 | 4066 | |
| 4024 | 4067 | const writer = f.object.writer(); |
| 4025 | 4068 | const local = try f.allocLocal(inst, inst_ty); |
| 4069 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 4026 | 4070 | try f.writeCValue(writer, local, .Other); |
| 4071 | try v.elem(f, writer); | |
| 4027 | 4072 | // (lhs <> rhs) ? lhs : rhs |
| 4028 | 4073 | try writer.writeAll(" = ("); |
| 4029 | 4074 | try f.writeCValue(writer, lhs, .Other); |
| 4075 | try v.elem(f, writer); | |
| 4030 | 4076 | try writer.writeByte(' '); |
| 4031 | 4077 | try writer.writeByte(operator); |
| 4032 | 4078 | try writer.writeByte(' '); |
| 4033 | 4079 | try f.writeCValue(writer, rhs, .Other); |
| 4080 | try v.elem(f, writer); | |
| 4034 | 4081 | try writer.writeAll(") ? "); |
| 4035 | 4082 | try f.writeCValue(writer, lhs, .Other); |
| 4083 | try v.elem(f, writer); | |
| 4036 | 4084 | try writer.writeAll(" : "); |
| 4037 | 4085 | try f.writeCValue(writer, rhs, .Other); |
| 4086 | try v.elem(f, writer); | |
| 4038 | 4087 | try writer.writeAll(";\n"); |
| 4088 | try v.end(f, inst, writer); | |
| 4039 | 4089 | |
| 4040 | 4090 | return local; |
| 4041 | 4091 | } |
| ... | ... | @@ -6002,30 +6052,35 @@ fn airUnBuiltinCall( |
| 6002 | 6052 | const operand = try f.resolveInst(ty_op.operand); |
| 6003 | 6053 | try reap(f, inst, &.{ty_op.operand}); |
| 6004 | 6054 | const inst_ty = f.air.typeOfIndex(inst); |
| 6055 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 6005 | 6056 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 6057 | const scalar_ty = operand_ty.scalarType(); | |
| 6006 | 6058 | |
| 6007 | const inst_cty = try f.typeToCType(inst_ty, .complete); | |
| 6008 | const ref_ret = switch (inst_cty.tag()) { | |
| 6009 | else => false, | |
| 6010 | .array, .vector => true, | |
| 6011 | }; | |
| 6059 | const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete); | |
| 6060 | const ref_ret = inst_scalar_cty.tag() == .array; | |
| 6012 | 6061 | |
| 6013 | 6062 | const writer = f.object.writer(); |
| 6014 | 6063 | const local = try f.allocLocal(inst, inst_ty); |
| 6064 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6015 | 6065 | if (!ref_ret) { |
| 6016 | 6066 | try f.writeCValue(writer, local, .Other); |
| 6067 | try v.elem(f, writer); | |
| 6017 | 6068 | try writer.writeAll(" = "); |
| 6018 | 6069 | } |
| 6019 | 6070 | try writer.print("zig_{s}_", .{operation}); |
| 6020 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 6071 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6021 | 6072 | try writer.writeByte('('); |
| 6022 | 6073 | if (ref_ret) { |
| 6023 | 6074 | try f.writeCValue(writer, local, .FunctionArgument); |
| 6075 | try v.elem(f, writer); | |
| 6024 | 6076 | try writer.writeAll(", "); |
| 6025 | 6077 | } |
| 6026 | 6078 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 6027 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | |
| 6079 | try v.elem(f, writer); | |
| 6080 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | |
| 6028 | 6081 | try writer.writeAll(");\n"); |
| 6082 | try v.end(f, inst, writer); | |
| 6083 | ||
| 6029 | 6084 | return local; |
| 6030 | 6085 | } |
| 6031 | 6086 | |
| ... | ... | @@ -6047,21 +6102,38 @@ fn airBinBuiltinCall( |
| 6047 | 6102 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6048 | 6103 | |
| 6049 | 6104 | const inst_ty = f.air.typeOfIndex(inst); |
| 6105 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 6050 | 6106 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 6107 | const scalar_ty = operand_ty.scalarType(); | |
| 6108 | ||
| 6109 | const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete); | |
| 6110 | const ref_ret = inst_scalar_cty.tag() == .array; | |
| 6051 | 6111 | |
| 6052 | 6112 | const writer = f.object.writer(); |
| 6053 | 6113 | const local = try f.allocLocal(inst, inst_ty); |
| 6054 | try f.writeCValue(writer, local, .Other); | |
| 6055 | try writer.writeAll(" = zig_"); | |
| 6056 | try writer.writeAll(operation); | |
| 6057 | try writer.writeByte('_'); | |
| 6058 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 6114 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6115 | if (!ref_ret) { | |
| 6116 | try f.writeCValue(writer, local, .Other); | |
| 6117 | try v.elem(f, writer); | |
| 6118 | try writer.writeAll(" = "); | |
| 6119 | } | |
| 6120 | try writer.print("zig_{s}_", .{operation}); | |
| 6121 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6059 | 6122 | try writer.writeByte('('); |
| 6123 | if (ref_ret) { | |
| 6124 | try f.writeCValue(writer, local, .FunctionArgument); | |
| 6125 | try v.elem(f, writer); | |
| 6126 | try writer.writeAll(", "); | |
| 6127 | } | |
| 6060 | 6128 | try f.writeCValue(writer, lhs, .FunctionArgument); |
| 6129 | try v.elem(f, writer); | |
| 6061 | 6130 | try writer.writeAll(", "); |
| 6062 | 6131 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 6063 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | |
| 6132 | try v.elem(f, writer); | |
| 6133 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | |
| 6064 | 6134 | try writer.writeAll(");\n"); |
| 6135 | try v.end(f, inst, writer); | |
| 6136 | ||
| 6065 | 6137 | return local; |
| 6066 | 6138 | } |
| 6067 | 6139 | |
| ... | ... | @@ -6073,45 +6145,56 @@ fn airCmpBuiltinCall( |
| 6073 | 6145 | operation: enum { cmp, operator }, |
| 6074 | 6146 | info: BuiltinInfo, |
| 6075 | 6147 | ) !CValue { |
| 6076 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6077 | const operand_ty = f.air.typeOf(data.lhs); | |
| 6148 | if (f.liveness.isUnused(inst)) { | |
| 6149 | try reap(f, inst, &.{ data.lhs, data.rhs }); | |
| 6150 | return .none; | |
| 6151 | } | |
| 6078 | 6152 | |
| 6079 | 6153 | const lhs = try f.resolveInst(data.lhs); |
| 6080 | 6154 | const rhs = try f.resolveInst(data.rhs); |
| 6081 | 6155 | try reap(f, inst, &.{ data.lhs, data.rhs }); |
| 6082 | 6156 | |
| 6083 | const inst_cty = try f.typeToCType(inst_ty, .complete); | |
| 6084 | const ref_ret = switch (inst_cty.tag()) { | |
| 6085 | else => false, | |
| 6086 | .array, .vector => true, | |
| 6087 | }; | |
| 6157 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6158 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 6159 | const operand_ty = f.air.typeOf(data.lhs); | |
| 6160 | const scalar_ty = operand_ty.scalarType(); | |
| 6161 | ||
| 6162 | const inst_scalar_cty = try f.typeToCType(inst_scalar_ty, .complete); | |
| 6163 | const ref_ret = inst_scalar_cty.tag() == .array; | |
| 6088 | 6164 | |
| 6089 | 6165 | const writer = f.object.writer(); |
| 6090 | 6166 | const local = try f.allocLocal(inst, inst_ty); |
| 6167 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6091 | 6168 | if (!ref_ret) { |
| 6092 | 6169 | try f.writeCValue(writer, local, .Other); |
| 6170 | try v.elem(f, writer); | |
| 6093 | 6171 | try writer.writeAll(" = "); |
| 6094 | 6172 | } |
| 6095 | 6173 | try writer.print("zig_{s}_", .{switch (operation) { |
| 6096 | 6174 | else => @tagName(operation), |
| 6097 | 6175 | .operator => compareOperatorAbbrev(operator), |
| 6098 | 6176 | }}); |
| 6099 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 6177 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6100 | 6178 | try writer.writeByte('('); |
| 6101 | 6179 | if (ref_ret) { |
| 6102 | 6180 | try f.writeCValue(writer, local, .FunctionArgument); |
| 6181 | try v.elem(f, writer); | |
| 6103 | 6182 | try writer.writeAll(", "); |
| 6104 | 6183 | } |
| 6105 | 6184 | try f.writeCValue(writer, lhs, .FunctionArgument); |
| 6185 | try v.elem(f, writer); | |
| 6106 | 6186 | try writer.writeAll(", "); |
| 6107 | 6187 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 6108 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | |
| 6188 | try v.elem(f, writer); | |
| 6189 | try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); | |
| 6109 | 6190 | try writer.writeByte(')'); |
| 6110 | 6191 | if (!ref_ret) try writer.print(" {s} {}", .{ |
| 6111 | 6192 | compareOperatorC(operator), |
| 6112 | 6193 | try f.fmtIntLiteral(Type.initTag(.i32), Value.zero), |
| 6113 | 6194 | }); |
| 6114 | 6195 | try writer.writeAll(";\n"); |
| 6196 | try v.end(f, inst, writer); | |
| 6197 | ||
| 6115 | 6198 | return local; |
| 6116 | 6199 | } |
| 6117 | 6200 | |
| ... | ... | @@ -6498,65 +6581,35 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6498 | 6581 | const operand = try f.resolveInst(reduce.operand); |
| 6499 | 6582 | try reap(f, inst, &.{reduce.operand}); |
| 6500 | 6583 | const operand_ty = f.air.typeOf(reduce.operand); |
| 6501 | const vector_len = operand_ty.vectorLen(); | |
| 6502 | 6584 | const writer = f.object.writer(); |
| 6503 | 6585 | |
| 6504 | const Op = union(enum) { | |
| 6505 | call_fn: []const u8, | |
| 6586 | const op: union(enum) { | |
| 6587 | float_op: []const u8, | |
| 6588 | builtin: []const u8, | |
| 6506 | 6589 | infix: []const u8, |
| 6507 | 6590 | ternary: []const u8, |
| 6508 | }; | |
| 6509 | var fn_name_buf: [64]u8 = undefined; | |
| 6510 | const op: Op = switch (reduce.operation) { | |
| 6591 | } = switch (reduce.operation) { | |
| 6511 | 6592 | .And => .{ .infix = " &= " }, |
| 6512 | 6593 | .Or => .{ .infix = " |= " }, |
| 6513 | 6594 | .Xor => .{ .infix = " ^= " }, |
| 6514 | 6595 | .Min => switch (scalar_ty.zigTypeTag()) { |
| 6515 | .Int => Op{ .ternary = " < " }, | |
| 6516 | .Float => op: { | |
| 6517 | const float_bits = scalar_ty.floatBits(target); | |
| 6518 | break :op Op{ | |
| 6519 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "{s}fmin{s}", .{ | |
| 6520 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | |
| 6521 | }) catch unreachable, | |
| 6522 | }; | |
| 6523 | }, | |
| 6596 | .Int => .{ .ternary = " < " }, | |
| 6597 | .Float => .{ .float_op = "fmin" }, | |
| 6524 | 6598 | else => unreachable, |
| 6525 | 6599 | }, |
| 6526 | 6600 | .Max => switch (scalar_ty.zigTypeTag()) { |
| 6527 | .Int => Op{ .ternary = " > " }, | |
| 6528 | .Float => op: { | |
| 6529 | const float_bits = scalar_ty.floatBits(target); | |
| 6530 | break :op Op{ | |
| 6531 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "{s}fmax{s}", .{ | |
| 6532 | libcFloatPrefix(float_bits), libcFloatSuffix(float_bits), | |
| 6533 | }) catch unreachable, | |
| 6534 | }; | |
| 6535 | }, | |
| 6601 | .Int => .{ .ternary = " > " }, | |
| 6602 | .Float => .{ .float_op = "fmax" }, | |
| 6536 | 6603 | else => unreachable, |
| 6537 | 6604 | }, |
| 6538 | 6605 | .Add => switch (scalar_ty.zigTypeTag()) { |
| 6539 | .Int => Op{ .infix = " += " }, | |
| 6540 | .Float => op: { | |
| 6541 | const float_bits = scalar_ty.floatBits(target); | |
| 6542 | break :op Op{ | |
| 6543 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "__add{s}f3", .{ | |
| 6544 | compilerRtFloatAbbrev(float_bits), | |
| 6545 | }) catch unreachable, | |
| 6546 | }; | |
| 6547 | }, | |
| 6606 | .Int => .{ .infix = " += " }, | |
| 6607 | .Float => .{ .builtin = "add" }, | |
| 6548 | 6608 | else => unreachable, |
| 6549 | 6609 | }, |
| 6550 | 6610 | .Mul => switch (scalar_ty.zigTypeTag()) { |
| 6551 | .Int => Op{ .infix = " *= " }, | |
| 6552 | .Float => op: { | |
| 6553 | const float_bits = scalar_ty.floatBits(target); | |
| 6554 | break :op Op{ | |
| 6555 | .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "__mul{s}f3", .{ | |
| 6556 | compilerRtFloatAbbrev(float_bits), | |
| 6557 | }) catch unreachable, | |
| 6558 | }; | |
| 6559 | }, | |
| 6611 | .Int => .{ .infix = " *= " }, | |
| 6612 | .Float => .{ .builtin = "mul" }, | |
| 6560 | 6613 | else => unreachable, |
| 6561 | 6614 | }, |
| 6562 | 6615 | }; |
| ... | ... | @@ -6572,75 +6625,94 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6572 | 6625 | // } |
| 6573 | 6626 | // break :reduce accum; |
| 6574 | 6627 | // } |
| 6575 | const it = try f.allocLocal(inst, Type.usize); | |
| 6576 | try f.writeCValue(writer, it, .Other); | |
| 6577 | try writer.writeAll(" = 0;\n"); | |
| 6578 | 6628 | |
| 6579 | 6629 | const accum = try f.allocLocal(inst, scalar_ty); |
| 6580 | 6630 | try f.writeCValue(writer, accum, .Other); |
| 6581 | 6631 | try writer.writeAll(" = "); |
| 6582 | 6632 | |
| 6583 | const init_val = switch (reduce.operation) { | |
| 6584 | .And, .Or, .Xor, .Add => "0", | |
| 6633 | var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa); | |
| 6634 | defer arena.deinit(); | |
| 6635 | ||
| 6636 | const ExpectedContents = union { | |
| 6637 | u: Value.Payload.U64, | |
| 6638 | i: Value.Payload.I64, | |
| 6639 | f16: Value.Payload.Float_16, | |
| 6640 | f32: Value.Payload.Float_32, | |
| 6641 | f64: Value.Payload.Float_64, | |
| 6642 | f80: Value.Payload.Float_80, | |
| 6643 | f128: Value.Payload.Float_128, | |
| 6644 | }; | |
| 6645 | var stack align(@alignOf(ExpectedContents)) = | |
| 6646 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | |
| 6647 | ||
| 6648 | try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) { | |
| 6649 | .Or, .Xor, .Add => Value.zero, | |
| 6650 | .And => switch (scalar_ty.zigTypeTag()) { | |
| 6651 | .Bool => Value.one, | |
| 6652 | else => switch (scalar_ty.intInfo(target).signedness) { | |
| 6653 | .unsigned => try scalar_ty.maxInt(stack.get(), target), | |
| 6654 | .signed => Value.negative_one, | |
| 6655 | }, | |
| 6656 | }, | |
| 6585 | 6657 | .Min => switch (scalar_ty.zigTypeTag()) { |
| 6586 | .Int => "TODO_intmax", | |
| 6587 | .Float => "TODO_nan", | |
| 6658 | .Bool => Value.one, | |
| 6659 | .Int => try scalar_ty.maxInt(stack.get(), target), | |
| 6660 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | |
| 6588 | 6661 | else => unreachable, |
| 6589 | 6662 | }, |
| 6590 | 6663 | .Max => switch (scalar_ty.zigTypeTag()) { |
| 6591 | .Int => "TODO_intmin", | |
| 6592 | .Float => "TODO_nan", | |
| 6664 | .Bool => Value.zero, | |
| 6665 | .Int => try scalar_ty.minInt(stack.get(), target), | |
| 6666 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | |
| 6593 | 6667 | else => unreachable, |
| 6594 | 6668 | }, |
| 6595 | .Mul => "1", | |
| 6596 | }; | |
| 6597 | try writer.writeAll(init_val); | |
| 6598 | try writer.writeAll(";"); | |
| 6599 | try f.object.indent_writer.insertNewline(); | |
| 6600 | try writer.writeAll("for (;"); | |
| 6601 | try f.writeCValue(writer, it, .Other); | |
| 6602 | try writer.print("<{d};++", .{vector_len}); | |
| 6603 | try f.writeCValue(writer, it, .Other); | |
| 6604 | try writer.writeAll(") "); | |
| 6605 | try f.writeCValue(writer, accum, .Other); | |
| 6669 | .Mul => Value.one, | |
| 6670 | }, .Initializer); | |
| 6671 | try writer.writeAll(";\n"); | |
| 6606 | 6672 | |
| 6673 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6674 | try f.writeCValue(writer, accum, .Other); | |
| 6607 | 6675 | switch (op) { |
| 6608 | .call_fn => |fn_name| { | |
| 6609 | try writer.print(" = {s}(", .{fn_name}); | |
| 6676 | .float_op => |operation| { | |
| 6677 | try writer.writeAll(" = zig_libc_name_"); | |
| 6678 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6679 | try writer.print("({s})(", .{operation}); | |
| 6680 | try f.writeCValue(writer, accum, .FunctionArgument); | |
| 6681 | try writer.writeAll(", "); | |
| 6682 | try f.writeCValue(writer, operand, .Other); | |
| 6683 | try v.elem(f, writer); | |
| 6684 | try writer.writeByte(')'); | |
| 6685 | }, | |
| 6686 | .builtin => |operation| { | |
| 6687 | try writer.print(" = zig_{s}_", .{operation}); | |
| 6688 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6689 | try writer.writeByte('('); | |
| 6610 | 6690 | try f.writeCValue(writer, accum, .FunctionArgument); |
| 6611 | 6691 | try writer.writeAll(", "); |
| 6612 | 6692 | try f.writeCValue(writer, operand, .Other); |
| 6613 | try writer.writeAll("["); | |
| 6614 | try f.writeCValue(writer, it, .Other); | |
| 6615 | try writer.writeAll("])"); | |
| 6693 | try v.elem(f, writer); | |
| 6694 | try writer.writeByte(')'); | |
| 6616 | 6695 | }, |
| 6617 | 6696 | .infix => |ass| { |
| 6618 | 6697 | try writer.writeAll(ass); |
| 6619 | 6698 | try f.writeCValue(writer, operand, .Other); |
| 6620 | try writer.writeAll("["); | |
| 6621 | try f.writeCValue(writer, it, .Other); | |
| 6622 | try writer.writeAll("]"); | |
| 6699 | try v.elem(f, writer); | |
| 6623 | 6700 | }, |
| 6624 | 6701 | .ternary => |cmp| { |
| 6625 | 6702 | try writer.writeAll(" = "); |
| 6626 | 6703 | try f.writeCValue(writer, accum, .Other); |
| 6627 | 6704 | try writer.writeAll(cmp); |
| 6628 | 6705 | try f.writeCValue(writer, operand, .Other); |
| 6629 | try writer.writeAll("["); | |
| 6630 | try f.writeCValue(writer, it, .Other); | |
| 6631 | try writer.writeAll("] ? "); | |
| 6706 | try v.elem(f, writer); | |
| 6707 | try writer.writeAll(" ? "); | |
| 6632 | 6708 | try f.writeCValue(writer, accum, .Other); |
| 6633 | 6709 | try writer.writeAll(" : "); |
| 6634 | 6710 | try f.writeCValue(writer, operand, .Other); |
| 6635 | try writer.writeAll("["); | |
| 6636 | try f.writeCValue(writer, it, .Other); | |
| 6637 | try writer.writeAll("]"); | |
| 6711 | try v.elem(f, writer); | |
| 6638 | 6712 | }, |
| 6639 | 6713 | } |
| 6640 | ||
| 6641 | 6714 | try writer.writeAll(";\n"); |
| 6642 | ||
| 6643 | try freeLocal(f, inst, it.new_local, 0); | |
| 6715 | try v.end(f, inst, writer); | |
| 6644 | 6716 | |
| 6645 | 6717 | return accum; |
| 6646 | 6718 | } |
| ... | ... | @@ -6774,7 +6846,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6774 | 6846 | try writer.writeByte('('); |
| 6775 | 6847 | |
| 6776 | 6848 | if (inst_ty.isAbiInt() and (field_ty.isAbiInt() or field_ty.isPtrAtRuntime())) { |
| 6777 | try f.renderIntCast(writer, inst_ty, element, field_ty, .FunctionArgument); | |
| 6849 | try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument); | |
| 6778 | 6850 | } else { |
| 6779 | 6851 | try writer.writeByte('('); |
| 6780 | 6852 | try f.renderType(writer, inst_ty); |
| ... | ... | @@ -6916,7 +6988,6 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6916 | 6988 | } |
| 6917 | 6989 | |
| 6918 | 6990 | fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6919 | const inst_ty = f.air.typeOfIndex(inst); | |
| 6920 | 6991 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 6921 | 6992 | if (f.liveness.isUnused(inst)) { |
| 6922 | 6993 | try reap(f, inst, &.{un_op}); |
| ... | ... | @@ -6925,16 +6996,23 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6925 | 6996 | |
| 6926 | 6997 | const operand = try f.resolveInst(un_op); |
| 6927 | 6998 | try reap(f, inst, &.{un_op}); |
| 6999 | ||
| 6928 | 7000 | const operand_ty = f.air.typeOf(un_op); |
| 7001 | const scalar_ty = operand_ty.scalarType(); | |
| 6929 | 7002 | |
| 6930 | 7003 | const writer = f.object.writer(); |
| 6931 | const local = try f.allocLocal(inst, inst_ty); | |
| 7004 | const local = try f.allocLocal(inst, operand_ty); | |
| 7005 | const v = try Vectorizer.start(f, inst, writer, operand_ty); | |
| 6932 | 7006 | try f.writeCValue(writer, local, .Other); |
| 7007 | try v.elem(f, writer); | |
| 6933 | 7008 | try writer.writeAll(" = zig_neg_"); |
| 6934 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 7009 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); | |
| 6935 | 7010 | try writer.writeByte('('); |
| 6936 | 7011 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 7012 | try v.elem(f, writer); | |
| 6937 | 7013 | try writer.writeAll(");\n"); |
| 7014 | try v.end(f, inst, writer); | |
| 7015 | ||
| 6938 | 7016 | return local; |
| 6939 | 7017 | } |
| 6940 | 7018 | |
| ... | ... | @@ -6944,19 +7022,28 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal |
| 6944 | 7022 | try reap(f, inst, &.{un_op}); |
| 6945 | 7023 | return .none; |
| 6946 | 7024 | } |
| 7025 | ||
| 6947 | 7026 | const operand = try f.resolveInst(un_op); |
| 6948 | 7027 | try reap(f, inst, &.{un_op}); |
| 6949 | const writer = f.object.writer(); | |
| 7028 | ||
| 6950 | 7029 | const inst_ty = f.air.typeOfIndex(inst); |
| 7030 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 7031 | ||
| 7032 | const writer = f.object.writer(); | |
| 6951 | 7033 | const local = try f.allocLocal(inst, inst_ty); |
| 7034 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6952 | 7035 | try f.writeCValue(writer, local, .Other); |
| 7036 | try v.elem(f, writer); | |
| 6953 | 7037 | try writer.writeAll(" = zig_libc_name_"); |
| 6954 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 7038 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); | |
| 6955 | 7039 | try writer.writeByte('('); |
| 6956 | 7040 | try writer.writeAll(operation); |
| 6957 | 7041 | try writer.writeAll(")("); |
| 6958 | 7042 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 7043 | try v.elem(f, writer); | |
| 6959 | 7044 | try writer.writeAll(");\n"); |
| 7045 | try v.end(f, inst, writer); | |
| 7046 | ||
| 6960 | 7047 | return local; |
| 6961 | 7048 | } |
| 6962 | 7049 | |
| ... | ... | @@ -6966,23 +7053,32 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa |
| 6966 | 7053 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6967 | 7054 | return .none; |
| 6968 | 7055 | } |
| 7056 | ||
| 6969 | 7057 | const lhs = try f.resolveInst(bin_op.lhs); |
| 6970 | 7058 | const rhs = try f.resolveInst(bin_op.rhs); |
| 6971 | 7059 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 6972 | 7060 | |
| 6973 | const writer = f.object.writer(); | |
| 6974 | 7061 | const inst_ty = f.air.typeOfIndex(inst); |
| 7062 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 7063 | ||
| 7064 | const writer = f.object.writer(); | |
| 6975 | 7065 | const local = try f.allocLocal(inst, inst_ty); |
| 7066 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 6976 | 7067 | try f.writeCValue(writer, local, .Other); |
| 7068 | try v.elem(f, writer); | |
| 6977 | 7069 | try writer.writeAll(" = zig_libc_name_"); |
| 6978 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 7070 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); | |
| 6979 | 7071 | try writer.writeByte('('); |
| 6980 | 7072 | try writer.writeAll(operation); |
| 6981 | 7073 | try writer.writeAll(")("); |
| 6982 | 7074 | try f.writeCValue(writer, lhs, .FunctionArgument); |
| 7075 | try v.elem(f, writer); | |
| 6983 | 7076 | try writer.writeAll(", "); |
| 6984 | 7077 | try f.writeCValue(writer, rhs, .FunctionArgument); |
| 7078 | try v.elem(f, writer); | |
| 6985 | 7079 | try writer.writeAll(");\n"); |
| 7080 | try v.end(f, inst, writer); | |
| 7081 | ||
| 6986 | 7082 | return local; |
| 6987 | 7083 | } |
| 6988 | 7084 | |
| ... | ... | @@ -6993,23 +7089,34 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6993 | 7089 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand }); |
| 6994 | 7090 | return .none; |
| 6995 | 7091 | } |
| 6996 | const inst_ty = f.air.typeOfIndex(inst); | |
| 7092 | ||
| 6997 | 7093 | const mulend1 = try f.resolveInst(bin_op.lhs); |
| 6998 | 7094 | const mulend2 = try f.resolveInst(bin_op.rhs); |
| 6999 | 7095 | const addend = try f.resolveInst(pl_op.operand); |
| 7000 | 7096 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand }); |
| 7097 | ||
| 7098 | const inst_ty = f.air.typeOfIndex(inst); | |
| 7099 | const inst_scalar_ty = inst_ty.scalarType(); | |
| 7100 | ||
| 7001 | 7101 | const writer = f.object.writer(); |
| 7002 | 7102 | const local = try f.allocLocal(inst, inst_ty); |
| 7103 | const v = try Vectorizer.start(f, inst, writer, inst_ty); | |
| 7003 | 7104 | try f.writeCValue(writer, local, .Other); |
| 7105 | try v.elem(f, writer); | |
| 7004 | 7106 | try writer.writeAll(" = zig_libc_name_"); |
| 7005 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 7107 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty); | |
| 7006 | 7108 | try writer.writeAll("(fma)("); |
| 7007 | 7109 | try f.writeCValue(writer, mulend1, .FunctionArgument); |
| 7110 | try v.elem(f, writer); | |
| 7008 | 7111 | try writer.writeAll(", "); |
| 7009 | 7112 | try f.writeCValue(writer, mulend2, .FunctionArgument); |
| 7113 | try v.elem(f, writer); | |
| 7010 | 7114 | try writer.writeAll(", "); |
| 7011 | 7115 | try f.writeCValue(writer, addend, .FunctionArgument); |
| 7116 | try v.elem(f, writer); | |
| 7012 | 7117 | try writer.writeAll(");\n"); |
| 7118 | try v.end(f, inst, writer); | |
| 7119 | ||
| 7013 | 7120 | return local; |
| 7014 | 7121 | } |
| 7015 | 7122 | |
| ... | ... | @@ -7510,6 +7617,47 @@ fn formatIntLiteral( |
| 7510 | 7617 | try data.cty.renderLiteralSuffix(writer); |
| 7511 | 7618 | } |
| 7512 | 7619 | |
| 7620 | const Vectorizer = struct { | |
| 7621 | index: CValue = .none, | |
| 7622 | ||
| 7623 | pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorizer { | |
| 7624 | return if (ty.zigTypeTag() == .Vector) index: { | |
| 7625 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() }; | |
| 7626 | ||
| 7627 | const local = try f.allocLocal(inst, Type.usize); | |
| 7628 | ||
| 7629 | try writer.writeAll("for ("); | |
| 7630 | try f.writeCValue(writer, local, .Other); | |
| 7631 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, Value.zero)}); | |
| 7632 | try f.writeCValue(writer, local, .Other); | |
| 7633 | try writer.print(" < {d}; ", .{ | |
| 7634 | try f.fmtIntLiteral(Type.usize, Value.initPayload(&len_pl.base)), | |
| 7635 | }); | |
| 7636 | try f.writeCValue(writer, local, .Other); | |
| 7637 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, Value.one)}); | |
| 7638 | f.object.indent_writer.pushIndent(); | |
| 7639 | ||
| 7640 | break :index .{ .index = local }; | |
| 7641 | } else .{}; | |
| 7642 | } | |
| 7643 | ||
| 7644 | pub fn elem(self: Vectorizer, f: *Function, writer: anytype) !void { | |
| 7645 | if (self.index != .none) { | |
| 7646 | try writer.writeByte('['); | |
| 7647 | try f.writeCValue(writer, self.index, .Other); | |
| 7648 | try writer.writeByte(']'); | |
| 7649 | } | |
| 7650 | } | |
| 7651 | ||
| 7652 | pub fn end(self: Vectorizer, f: *Function, inst: Air.Inst.Index, writer: anytype) !void { | |
| 7653 | if (self.index != .none) { | |
| 7654 | f.object.indent_writer.popIndent(); | |
| 7655 | try writer.writeAll("}\n"); | |
| 7656 | try freeLocal(f, inst, self.index.new_local, 0); | |
| 7657 | } | |
| 7658 | } | |
| 7659 | }; | |
| 7660 | ||
| 7513 | 7661 | fn isByRef(ty: Type) bool { |
| 7514 | 7662 | _ = ty; |
| 7515 | 7663 | return false; |
src/type.zig+1-1| ... | ... | @@ -4213,7 +4213,7 @@ pub const Type = extern union { |
| 4213 | 4213 | }; |
| 4214 | 4214 | } |
| 4215 | 4215 | |
| 4216 | pub fn shallowElemType(child_ty: Type) Type { | |
| 4216 | fn shallowElemType(child_ty: Type) Type { | |
| 4217 | 4217 | return switch (child_ty.zigTypeTag()) { |
| 4218 | 4218 | .Array, .Vector => child_ty.childType(), |
| 4219 | 4219 | else => child_ty, |
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/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/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/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-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,7 +191,6 @@ 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 |
test/behavior/vector.zig+10-22| ... | ... | @@ -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 |
| ... | ... | @@ -116,7 +115,6 @@ test "vector float operators" { |
| 116 | 115 | |
| 117 | 116 | test "vector bit operators" { |
| 118 | 117 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 119 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 120 | 118 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 121 | 119 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 122 | 120 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -442,7 +440,6 @@ test "vector comparison operators" { |
| 442 | 440 | |
| 443 | 441 | test "vector division operators" { |
| 444 | 442 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 445 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 446 | 443 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 447 | 444 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 448 | 445 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -525,7 +522,6 @@ test "vector division operators" { |
| 525 | 522 | |
| 526 | 523 | test "vector bitwise not operator" { |
| 527 | 524 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 528 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 529 | 525 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 530 | 526 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 531 | 527 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -557,7 +553,6 @@ test "vector bitwise not operator" { |
| 557 | 553 | |
| 558 | 554 | test "vector shift operators" { |
| 559 | 555 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 560 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 561 | 556 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 562 | 557 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 563 | 558 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -651,7 +646,6 @@ test "vector shift operators" { |
| 651 | 646 | |
| 652 | 647 | test "vector reduce operation" { |
| 653 | 648 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 654 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 655 | 649 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 656 | 650 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 657 | 651 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -707,7 +701,7 @@ test "vector reduce operation" { |
| 707 | 701 | |
| 708 | 702 | // LLVM 11 ERROR: Cannot select type |
| 709 | 703 | // https://github.com/ziglang/zig/issues/7138 |
| 710 | if (builtin.target.cpu.arch != .aarch64) { | |
| 704 | if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) { | |
| 711 | 705 | try testReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386)); |
| 712 | 706 | try testReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9)); |
| 713 | 707 | } |
| ... | ... | @@ -725,7 +719,7 @@ test "vector reduce operation" { |
| 725 | 719 | |
| 726 | 720 | // LLVM 11 ERROR: Cannot select type |
| 727 | 721 | // https://github.com/ziglang/zig/issues/7138 |
| 728 | if (builtin.target.cpu.arch != .aarch64) { | |
| 722 | if (builtin.zig_backend != .stage2_llvm or builtin.target.cpu.arch != .aarch64) { | |
| 729 | 723 | try testReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567)); |
| 730 | 724 | try testReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999)); |
| 731 | 725 | } |
| ... | ... | @@ -773,14 +767,14 @@ test "vector reduce operation" { |
| 773 | 767 | |
| 774 | 768 | // LLVM 11 ERROR: Cannot select type |
| 775 | 769 | // https://github.com/ziglang/zig/issues/7138 |
| 776 | if (false) { | |
| 777 | try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 778 | try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 779 | try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 780 | ||
| 781 | try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 782 | try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 783 | try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 770 | if (builtin.zig_backend != .stage2_llvm) { | |
| 771 | try testReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, -1.9)); | |
| 772 | try testReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, -1.9)); | |
| 773 | try testReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, -1.9)); | |
| 774 | ||
| 775 | try testReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, @as(f16, 100.0)); | |
| 776 | try testReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, @as(f32, 100.0)); | |
| 777 | try testReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, @as(f64, 100.0)); | |
| 784 | 778 | } |
| 785 | 779 | |
| 786 | 780 | try testReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); |
| ... | ... | @@ -831,7 +825,6 @@ test "mask parameter of @shuffle is comptime scope" { |
| 831 | 825 | |
| 832 | 826 | test "saturating add" { |
| 833 | 827 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 834 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 835 | 828 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 836 | 829 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 837 | 830 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -863,7 +856,6 @@ test "saturating add" { |
| 863 | 856 | |
| 864 | 857 | test "saturating subtraction" { |
| 865 | 858 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 866 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 867 | 859 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 868 | 860 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 869 | 861 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -886,7 +878,6 @@ test "saturating subtraction" { |
| 886 | 878 | |
| 887 | 879 | test "saturating multiplication" { |
| 888 | 880 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 889 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 890 | 881 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 891 | 882 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 892 | 883 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -913,7 +904,6 @@ test "saturating multiplication" { |
| 913 | 904 | |
| 914 | 905 | test "saturating shift-left" { |
| 915 | 906 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 916 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 917 | 907 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 918 | 908 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 919 | 909 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1047,7 +1037,6 @@ test "@mulWithOverflow" { |
| 1047 | 1037 | } |
| 1048 | 1038 | |
| 1049 | 1039 | test "@shlWithOverflow" { |
| 1050 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1051 | 1040 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1052 | 1041 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1053 | 1042 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1202,7 +1191,6 @@ test "zero multiplicand" { |
| 1202 | 1191 | |
| 1203 | 1192 | test "@intCast to u0" { |
| 1204 | 1193 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1205 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1206 | 1194 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1207 | 1195 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1208 | 1196 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |