authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-05 14:48:06-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-03-05 14:48:06-05:00
log7b01af2bfd4cf9232fb0157c26d7c59642452fab
tree733810a59ad5a4177198d60b9058e2951567a94a
parenta63134a4a56e8683aeee292b641b4e943cbfb999
parent1efd36cd5c9a1128ae702b081d60ee32f21bc258
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14745 from jacobly0/bigint

CBE: add support for integers larger than 128 bits (and apparently vectors too)

21 files changed, 2445 insertions(+), 857 deletions(-)

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