authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-02 17:55:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-03 03:21:53-05:00
log5bd69c655d9e04102c8a64ced1215c9d69f4f03f
treef9cc0357049aa717d27f001758c5401f57a46f4c
parentc9ef277fa7e43f119a7f2896635b4fdf9c97edbe

zig.h: support GCC compilers that lack __has_builtin


1 files changed, 48 insertions(+), 52 deletions(-)

lib/zig.h+48-52
......@@ -90,7 +90,7 @@ typedef char bool;
9090#define zig_align_fn zig_align_fn_unavailable
9191#endif
9292
93#if zig_has_builtin(unreachable)
93#if zig_has_builtin(unreachable) || defined(__GNUC__)
9494#define zig_unreachable() __builtin_unreachable()
9595#else
9696#define zig_unreachable()
......@@ -113,7 +113,7 @@ typedef char bool;
113113
114114#if zig_has_builtin(debugtrap)
115115#define zig_breakpoint() __builtin_debugtrap()
116#elif zig_has_builtin(trap)
116#elif zig_has_builtin(trap) || defined(__GNUC__)
117117#define zig_breakpoint() __builtin_trap()
118118#elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
119119#define zig_breakpoint() __debugbreak()
......@@ -123,7 +123,7 @@ typedef char bool;
123123#define zig_breakpoint() raise(SIGTRAP)
124124#endif
125125
126#if zig_has_builtin(return_address)
126#if zig_has_builtin(return_address) || defined(__GNUC__)
127127#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))
128128#elif defined(_MSC_VER)
129129#define zig_return_address() _ReturnAddress()
......@@ -131,13 +131,13 @@ typedef char bool;
131131#define zig_return_address() 0
132132#endif
133133
134#if zig_has_builtin(frame_address)
134#if zig_has_builtin(frame_address) || defined(__GNUC__)
135135#define zig_frame_address() __builtin_frame_address(0)
136136#else
137137#define zig_frame_address() 0
138138#endif
139139
140#if zig_has_builtin(prefetch)
140#if zig_has_builtin(prefetch) || defined(__GNUC__)
141141#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
142142#else
143143#define zig_prefetch(addr, rw, locality)
......@@ -412,7 +412,7 @@ zig_int_helpers(32)
412412zig_int_helpers(64)
413413
414414static inline bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
415#if zig_has_builtin(add_overflow)
415#if zig_has_builtin(add_overflow) || defined(__GNUC__)
416416 zig_u32 full_res;
417417 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
418418 *res = zig_wrap_u32(full_res, bits);
......@@ -431,7 +431,7 @@ static inline void zig_vaddo_u32(zig_u8 *ov, zig_u32 *res, int n,
431431
432432zig_extern zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
433433static inline bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
434#if zig_has_builtin(add_overflow)
434#if zig_has_builtin(add_overflow) || defined(__GNUC__)
435435 zig_i32 full_res;
436436 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
437437#else
......@@ -450,7 +450,7 @@ static inline void zig_vaddo_i32(zig_u8 *ov, zig_i32 *res, int n,
450450}
451451
452452static inline bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
453#if zig_has_builtin(add_overflow)
453#if zig_has_builtin(add_overflow) || defined(__GNUC__)
454454 zig_u64 full_res;
455455 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
456456 *res = zig_wrap_u64(full_res, bits);
......@@ -469,7 +469,7 @@ static inline void zig_vaddo_u64(zig_u8 *ov, zig_u64 *res, int n,
469469
470470zig_extern zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
471471static inline bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
472#if zig_has_builtin(add_overflow)
472#if zig_has_builtin(add_overflow) || defined(__GNUC__)
473473 zig_i64 full_res;
474474 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
475475#else
......@@ -488,7 +488,7 @@ static inline void zig_vaddo_i64(zig_u8 *ov, zig_i64 *res, int n,
488488}
489489
490490static inline bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
491#if zig_has_builtin(add_overflow)
491#if zig_has_builtin(add_overflow) || defined(__GNUC__)
492492 zig_u8 full_res;
493493 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
494494 *res = zig_wrap_u8(full_res, bits);
......@@ -508,7 +508,7 @@ static inline void zig_vaddo_u8(zig_u8 *ov, zig_u8 *res, int n,
508508}
509509
510510static inline bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
511#if zig_has_builtin(add_overflow)
511#if zig_has_builtin(add_overflow) || defined(__GNUC__)
512512 zig_i8 full_res;
513513 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
514514 *res = zig_wrap_i8(full_res, bits);
......@@ -528,7 +528,7 @@ static inline void zig_vaddo_i8(zig_u8 *ov, zig_i8 *res, int n,
528528}
529529
530530static inline bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
531#if zig_has_builtin(add_overflow)
531#if zig_has_builtin(add_overflow) || defined(__GNUC__)
532532 zig_u16 full_res;
533533 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
534534 *res = zig_wrap_u16(full_res, bits);
......@@ -548,7 +548,7 @@ static inline void zig_vaddo_u16(zig_u8 *ov, zig_u16 *res, int n,
548548}
549549
550550static inline bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
551#if zig_has_builtin(add_overflow)
551#if zig_has_builtin(add_overflow) || defined(__GNUC__)
552552 zig_i16 full_res;
553553 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
554554 *res = zig_wrap_i16(full_res, bits);
......@@ -568,7 +568,7 @@ static inline void zig_vaddo_i16(zig_u8 *ov, zig_i16 *res, int n,
568568}
569569
570570static inline bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
571#if zig_has_builtin(sub_overflow)
571#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
572572 zig_u32 full_res;
573573 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
574574 *res = zig_wrap_u32(full_res, bits);
......@@ -587,7 +587,7 @@ static inline void zig_vsubo_u32(zig_u8 *ov, zig_u32 *res, int n,
587587
588588zig_extern zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
589589static inline bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
590#if zig_has_builtin(sub_overflow)
590#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
591591 zig_i32 full_res;
592592 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
593593#else
......@@ -606,7 +606,7 @@ static inline void zig_vsubo_i32(zig_u8 *ov, zig_i32 *res, int n,
606606}
607607
608608static inline bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
609#if zig_has_builtin(sub_overflow)
609#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
610610 zig_u64 full_res;
611611 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
612612 *res = zig_wrap_u64(full_res, bits);
......@@ -625,7 +625,7 @@ static inline void zig_vsubo_u64(zig_u8 *ov, zig_u64 *res, int n,
625625
626626zig_extern zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
627627static inline bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
628#if zig_has_builtin(sub_overflow)
628#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
629629 zig_i64 full_res;
630630 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
631631#else
......@@ -644,7 +644,7 @@ static inline void zig_vsubo_i64(zig_u8 *ov, zig_i64 *res, int n,
644644}
645645
646646static inline bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
647#if zig_has_builtin(sub_overflow)
647#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
648648 zig_u8 full_res;
649649 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
650650 *res = zig_wrap_u8(full_res, bits);
......@@ -664,7 +664,7 @@ static inline void zig_vsubo_u8(zig_u8 *ov, zig_u8 *res, int n,
664664}
665665
666666static inline bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
667#if zig_has_builtin(sub_overflow)
667#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
668668 zig_i8 full_res;
669669 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
670670 *res = zig_wrap_i8(full_res, bits);
......@@ -685,7 +685,7 @@ static inline void zig_vsubo_i8(zig_u8 *ov, zig_i8 *res, int n,
685685
686686
687687static inline bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
688#if zig_has_builtin(sub_overflow)
688#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
689689 zig_u16 full_res;
690690 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
691691 *res = zig_wrap_u16(full_res, bits);
......@@ -706,7 +706,7 @@ static inline void zig_vsubo_u16(zig_u8 *ov, zig_u16 *res, int n,
706706
707707
708708static inline bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
709#if zig_has_builtin(sub_overflow)
709#if zig_has_builtin(sub_overflow) || defined(__GNUC__)
710710 zig_i16 full_res;
711711 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
712712 *res = zig_wrap_i16(full_res, bits);
......@@ -726,7 +726,7 @@ static inline void zig_vsubo_i16(zig_u8 *ov, zig_i16 *res, int n,
726726}
727727
728728static inline bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
729#if zig_has_builtin(mul_overflow)
729#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
730730 zig_u32 full_res;
731731 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
732732 *res = zig_wrap_u32(full_res, bits);
......@@ -745,7 +745,7 @@ static inline void zig_vmulo_u32(zig_u8 *ov, zig_u32 *res, int n,
745745
746746zig_extern zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
747747static inline bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
748#if zig_has_builtin(mul_overflow)
748#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
749749 zig_i32 full_res;
750750 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
751751#else
......@@ -764,7 +764,7 @@ static inline void zig_vmulo_i32(zig_u8 *ov, zig_i32 *res, int n,
764764}
765765
766766static inline bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
767#if zig_has_builtin(mul_overflow)
767#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
768768 zig_u64 full_res;
769769 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
770770 *res = zig_wrap_u64(full_res, bits);
......@@ -783,7 +783,7 @@ static inline void zig_vmulo_u64(zig_u8 *ov, zig_u64 *res, int n,
783783
784784zig_extern zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
785785static inline bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
786#if zig_has_builtin(mul_overflow)
786#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
787787 zig_i64 full_res;
788788 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
789789#else
......@@ -802,7 +802,7 @@ static inline void zig_vmulo_i64(zig_u8 *ov, zig_i64 *res, int n,
802802}
803803
804804static inline bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
805#if zig_has_builtin(mul_overflow)
805#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
806806 zig_u8 full_res;
807807 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
808808 *res = zig_wrap_u8(full_res, bits);
......@@ -822,7 +822,7 @@ static inline void zig_vmulo_u8(zig_u8 *ov, zig_u8 *res, int n,
822822}
823823
824824static inline bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
825#if zig_has_builtin(mul_overflow)
825#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
826826 zig_i8 full_res;
827827 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
828828 *res = zig_wrap_i8(full_res, bits);
......@@ -842,7 +842,7 @@ static inline void zig_vmulo_i8(zig_u8 *ov, zig_i8 *res, int n,
842842}
843843
844844static inline bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
845#if zig_has_builtin(mul_overflow)
845#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
846846 zig_u16 full_res;
847847 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
848848 *res = zig_wrap_u16(full_res, bits);
......@@ -862,7 +862,7 @@ static inline void zig_vmulo_u16(zig_u8 *ov, zig_u16 *res, int n,
862862}
863863
864864static inline bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
865#if zig_has_builtin(mul_overflow)
865#if zig_has_builtin(mul_overflow) || defined(__GNUC__)
866866 zig_i16 full_res;
867867 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
868868 *res = zig_wrap_i16(full_res, bits);
......@@ -977,7 +977,7 @@ static inline zig_i8 zig_byte_swap_i8(zig_i8 val, zig_u8 bits) {
977977
978978static inline zig_u16 zig_byte_swap_u16(zig_u16 val, zig_u8 bits) {
979979 zig_u16 full_res;
980#if zig_has_builtin(bswap16)
980#if zig_has_builtin(bswap16) || defined(__GNUC__)
981981 full_res = __builtin_bswap16(val);
982982#else
983983 full_res = (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 0), 8) << 8 |
......@@ -992,7 +992,7 @@ static inline zig_i16 zig_byte_swap_i16(zig_i16 val, zig_u8 bits) {
992992
993993static inline zig_u32 zig_byte_swap_u32(zig_u32 val, zig_u8 bits) {
994994 zig_u32 full_res;
995#if zig_has_builtin(bswap32)
995#if zig_has_builtin(bswap32) || defined(__GNUC__)
996996 full_res = __builtin_bswap32(val);
997997#else
998998 full_res = (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 0), 16) << 16 |
......@@ -1007,7 +1007,7 @@ static inline zig_i32 zig_byte_swap_i32(zig_i32 val, zig_u8 bits) {
10071007
10081008static inline zig_u64 zig_byte_swap_u64(zig_u64 val, zig_u8 bits) {
10091009 zig_u64 full_res;
1010#if zig_has_builtin(bswap64)
1010#if zig_has_builtin(bswap64) || defined(__GNUC__)
10111011 full_res = __builtin_bswap64(val);
10121012#else
10131013 full_res = (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 0), 32) << 32 |
......@@ -1087,7 +1087,7 @@ static inline zig_i64 zig_bit_reverse_i64(zig_i64 val, zig_u8 bits) {
10871087 static inline zig_u8 zig_popcount_i##w(zig_i##w val, zig_u8 bits) { \
10881088 return zig_popcount_u##w((zig_u##w)val, bits); \
10891089 }
1090#if zig_has_builtin(popcount)
1090#if zig_has_builtin(popcount) || defined(__GNUC__)
10911091#define zig_builtin_popcount(w) \
10921092 static inline zig_u8 zig_popcount_u##w(zig_u##w val, zig_u8 bits) { \
10931093 (void)bits; \
......@@ -1116,7 +1116,7 @@ zig_builtin_popcount(64)
11161116 static inline zig_u8 zig_ctz_i##w(zig_i##w val, zig_u8 bits) { \
11171117 return zig_ctz_u##w((zig_u##w)val, bits); \
11181118 }
1119#if zig_has_builtin(ctz)
1119#if zig_has_builtin(ctz) || defined(__GNUC__)
11201120#define zig_builtin_ctz(w) \
11211121 static inline zig_u8 zig_ctz_u##w(zig_u##w val, zig_u8 bits) { \
11221122 if (val == 0) return bits; \
......@@ -1141,7 +1141,7 @@ zig_builtin_ctz(64)
11411141 static inline zig_u8 zig_clz_i##w(zig_i##w val, zig_u8 bits) { \
11421142 return zig_clz_u##w((zig_u##w)val, bits); \
11431143 }
1144#if zig_has_builtin(clz)
1144#if zig_has_builtin(clz) || defined(__GNUC__)
11451145#define zig_builtin_clz(w) \
11461146 static inline zig_u8 zig_clz_u##w(zig_u##w val, zig_u8 bits) { \
11471147 if (val == 0) return bits; \
......@@ -1764,8 +1764,8 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) {
17641764#define __builtin_infl() zig_msvc_flt_infl
17651765#endif
17661766
1767#define zig_has_float_builtins (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf))
1768#if zig_has_float_builtins
1767
1768#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(__GNUC__)
17691769#define zig_as_special_f16(sign, name, arg, repr) sign zig_as_f16(__builtin_##name, )(arg)
17701770#define zig_as_special_f32(sign, name, arg, repr) sign zig_as_f32(__builtin_##name, )(arg)
17711771#define zig_as_special_f64(sign, name, arg, repr) sign zig_as_f64(__builtin_##name, )(arg)
......@@ -1773,6 +1773,16 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) {
17731773#define zig_as_special_f128(sign, name, arg, repr) sign zig_as_f128(__builtin_##name, )(arg)
17741774#define zig_as_special_c_longdouble(sign, name, arg, repr) sign zig_as_c_longdouble(__builtin_##name, )(arg)
17751775#else
1776#define zig_float_from_repr(Type, ReprType) \
1777 static inline zig_##Type zig_float_from_repr_##Type(zig_##ReprType repr) { \
1778 return *((zig_##Type*)&repr); \
1779 }
1780zig_float_from_repr(f16, u16)
1781zig_float_from_repr(f32, u32)
1782zig_float_from_repr(f64, u64)
1783zig_float_from_repr(f80, u128)
1784zig_float_from_repr(f128, u128)
1785zig_float_from_repr(c_longdouble, u128)
17761786#define zig_as_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr)
17771787#define zig_as_special_f32(sign, name, arg, repr) zig_float_from_repr_f32(repr)
17781788#define zig_as_special_f64(sign, name, arg, repr) zig_float_from_repr_f64(repr)
......@@ -1795,7 +1805,7 @@ typedef double zig_f16;
17951805#define zig_bitSizeOf_c_longdouble 16
17961806typedef long double zig_f16;
17971807#define zig_as_f16(fp, repr) fp##l
1798#elif FLT16_MANT_DIG == 11 && zig_has_builtin(inff16)
1808#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(__GNUC__))
17991809typedef _Float16 zig_f16;
18001810#define zig_as_f16(fp, repr) fp##f16
18011811#elif defined(__SIZEOF_FP16__)
......@@ -1974,20 +1984,6 @@ typedef zig_i128 zig_c_longdouble;
19741984#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr
19751985#endif
19761986
1977#if !zig_has_float_builtins
1978#define zig_float_from_repr(Type, ReprType) \
1979 static inline zig_##Type zig_float_from_repr_##Type(zig_##ReprType repr) { \
1980 return *((zig_##Type*)&repr); \
1981 }
1982
1983zig_float_from_repr(f16, u16)
1984zig_float_from_repr(f32, u32)
1985zig_float_from_repr(f64, u64)
1986zig_float_from_repr(f80, u128)
1987zig_float_from_repr(f128, u128)
1988zig_float_from_repr(c_longdouble, u128)
1989#endif
1990
19911987#define zig_cast_f16 (zig_f16)
19921988#define zig_cast_f32 (zig_f32)
19931989#define zig_cast_f64 (zig_f64)