authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-09 22:19:40-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-09 22:19:40-05:00
loge945045437f6d3b60e308bf5116291cb78bdef49
tree81a6cd10074e0d79e006ce8416051be6e8a3024e
parentf7fea080b25f932b352d38f126e0a179c5163f68
parenta2854f71dc455f495d7967f1ac6d745f4cfa3a17
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13850 from jacobly0/builtin-fallback

zig.h: fix and add builtin fallbacks

1 files changed, 172 insertions(+), 106 deletions(-)

lib/zig.h+172-106
...@@ -335,6 +335,38 @@ zig_extern void *memset (void *, int, zig_usize);...@@ -335,6 +335,38 @@ zig_extern void *memset (void *, int, zig_usize);
335 static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \335 static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \
336 zig_i##w rem = lhs % rhs; \336 zig_i##w rem = lhs % rhs; \
337 return rem + (((lhs ^ rhs) & rem) < zig_as_i##w(0) ? rhs : zig_as_i##w(0)); \337 return rem + (((lhs ^ rhs) & rem) < zig_as_i##w(0) ? rhs : zig_as_i##w(0)); \
338 } \
339\
340 static inline zig_u##w zig_shlw_u##w(zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \
341 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \
342 } \
343\
344 static inline zig_i##w zig_shlw_i##w(zig_i##w lhs, zig_u8 rhs, zig_u8 bits) { \
345 return zig_wrap_i##w((zig_i##w)zig_shl_u##w((zig_u##w)lhs, (zig_u##w)rhs), bits); \
346 } \
347\
348 static inline zig_u##w zig_addw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
349 return zig_wrap_u##w(lhs + rhs, bits); \
350 } \
351\
352 static inline zig_i##w zig_addw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
353 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs + (zig_u##w)rhs), bits); \
354 } \
355\
356 static inline zig_u##w zig_subw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
357 return zig_wrap_u##w(lhs - rhs, bits); \
358 } \
359\
360 static inline zig_i##w zig_subw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
361 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs - (zig_u##w)rhs), bits); \
362 } \
363\
364 static inline zig_u##w zig_mulw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
365 return zig_wrap_u##w(lhs * rhs, bits); \
366 } \
367\
368 static inline zig_i##w zig_mulw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
369 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs * (zig_u##w)rhs), bits); \
338 }370 }
339zig_int_helpers(8)371zig_int_helpers(8)
340zig_int_helpers(16)372zig_int_helpers(16)
...@@ -366,7 +398,7 @@ static inline bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 b...@@ -366,7 +398,7 @@ static inline bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 b
366 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);398 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
367#else399#else
368 zig_c_int overflow_int;400 zig_c_int overflow_int;
369 zig_u32 full_res = __addosi4(lhs, rhs, &overflow_int);401 zig_i32 full_res = __addosi4(lhs, rhs, &overflow_int);
370 bool overflow = overflow_int != 0;402 bool overflow = overflow_int != 0;
371#endif403#endif
372 *res = zig_wrap_i32(full_res, bits);404 *res = zig_wrap_i32(full_res, bits);
...@@ -404,7 +436,7 @@ static inline bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 b...@@ -404,7 +436,7 @@ static inline bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 b
404 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);436 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
405#else437#else
406 zig_c_int overflow_int;438 zig_c_int overflow_int;
407 zig_u64 full_res = __addodi4(lhs, rhs, &overflow_int);439 zig_i64 full_res = __addodi4(lhs, rhs, &overflow_int);
408 bool overflow = overflow_int != 0;440 bool overflow = overflow_int != 0;
409#endif441#endif
410 *res = zig_wrap_i64(full_res, bits);442 *res = zig_wrap_i64(full_res, bits);
...@@ -424,7 +456,10 @@ static inline bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits)...@@ -424,7 +456,10 @@ static inline bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits)
424 *res = zig_wrap_u8(full_res, bits);456 *res = zig_wrap_u8(full_res, bits);
425 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);457 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);
426#else458#else
427 return zig_addo_u32(res, lhs, rhs, bits);459 zig_u32 full_res;
460 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
461 *res = (zig_u8)full_res;
462 return overflow;
428#endif463#endif
429}464}
430465
...@@ -441,7 +476,10 @@ static inline bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits)...@@ -441,7 +476,10 @@ static inline bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits)
441 *res = zig_wrap_i8(full_res, bits);476 *res = zig_wrap_i8(full_res, bits);
442 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);477 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);
443#else478#else
444 return zig_addo_i32(res, lhs, rhs, bits);479 zig_i32 full_res;
480 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
481 *res = (zig_i8)full_res;
482 return overflow;
445#endif483#endif
446}484}
447485
...@@ -458,7 +496,10 @@ static inline bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 b...@@ -458,7 +496,10 @@ static inline bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 b
458 *res = zig_wrap_u16(full_res, bits);496 *res = zig_wrap_u16(full_res, bits);
459 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);497 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);
460#else498#else
461 return zig_addo_u32(res, lhs, rhs, bits);499 zig_u32 full_res;
500 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
501 *res = (zig_u16)full_res;
502 return overflow;
462#endif503#endif
463}504}
464505
...@@ -475,7 +516,10 @@ static inline bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 b...@@ -475,7 +516,10 @@ static inline bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 b
475 *res = zig_wrap_i16(full_res, bits);516 *res = zig_wrap_i16(full_res, bits);
476 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);517 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);
477#else518#else
478 return zig_addo_i32(res, lhs, rhs, bits);519 zig_i32 full_res;
520 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
521 *res = (zig_i16)full_res;
522 return overflow;
479#endif523#endif
480}524}
481525
...@@ -510,7 +554,7 @@ static inline bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 b...@@ -510,7 +554,7 @@ static inline bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 b
510 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);554 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
511#else555#else
512 zig_c_int overflow_int;556 zig_c_int overflow_int;
513 zig_u32 full_res = __subosi4(lhs, rhs, &overflow_int);557 zig_i32 full_res = __subosi4(lhs, rhs, &overflow_int);
514 bool overflow = overflow_int != 0;558 bool overflow = overflow_int != 0;
515#endif559#endif
516 *res = zig_wrap_i32(full_res, bits);560 *res = zig_wrap_i32(full_res, bits);
...@@ -548,7 +592,7 @@ static inline bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 b...@@ -548,7 +592,7 @@ static inline bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 b
548 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);592 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
549#else593#else
550 zig_c_int overflow_int;594 zig_c_int overflow_int;
551 zig_u64 full_res = __subodi4(lhs, rhs, &overflow_int);595 zig_i64 full_res = __subodi4(lhs, rhs, &overflow_int);
552 bool overflow = overflow_int != 0;596 bool overflow = overflow_int != 0;
553#endif597#endif
554 *res = zig_wrap_i64(full_res, bits);598 *res = zig_wrap_i64(full_res, bits);
...@@ -568,7 +612,10 @@ static inline bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits)...@@ -568,7 +612,10 @@ static inline bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits)
568 *res = zig_wrap_u8(full_res, bits);612 *res = zig_wrap_u8(full_res, bits);
569 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);613 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);
570#else614#else
571 return zig_subo_u32(res, lhs, rhs, bits);615 zig_u32 full_res;
616 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
617 *res = (zig_u8)full_res;
618 return overflow;
572#endif619#endif
573}620}
574621
...@@ -585,7 +632,10 @@ static inline bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits)...@@ -585,7 +632,10 @@ static inline bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits)
585 *res = zig_wrap_i8(full_res, bits);632 *res = zig_wrap_i8(full_res, bits);
586 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);633 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);
587#else634#else
588 return zig_subo_i32(res, lhs, rhs, bits);635 zig_i32 full_res;
636 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
637 *res = (zig_i8)full_res;
638 return overflow;
589#endif639#endif
590}640}
591641
...@@ -603,7 +653,10 @@ static inline bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 b...@@ -603,7 +653,10 @@ static inline bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 b
603 *res = zig_wrap_u16(full_res, bits);653 *res = zig_wrap_u16(full_res, bits);
604 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);654 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);
605#else655#else
606 return zig_subo_u32(res, lhs, rhs, bits);656 zig_u32 full_res;
657 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
658 *res = (zig_u16)full_res;
659 return overflow;
607#endif660#endif
608}661}
609662
...@@ -621,7 +674,10 @@ static inline bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 b...@@ -621,7 +674,10 @@ static inline bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 b
621 *res = zig_wrap_i16(full_res, bits);674 *res = zig_wrap_i16(full_res, bits);
622 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);675 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);
623#else676#else
624 return zig_subo_i32(res, lhs, rhs, bits);677 zig_i32 full_res;
678 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
679 *res = (zig_i16)full_res;
680 return overflow;
625#endif681#endif
626}682}
627683
...@@ -656,7 +712,7 @@ static inline bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 b...@@ -656,7 +712,7 @@ static inline bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 b
656 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);712 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
657#else713#else
658 zig_c_int overflow_int;714 zig_c_int overflow_int;
659 zig_u32 full_res = __mulosi4(lhs, rhs, &overflow_int);715 zig_i32 full_res = __mulosi4(lhs, rhs, &overflow_int);
660 bool overflow = overflow_int != 0;716 bool overflow = overflow_int != 0;
661#endif717#endif
662 *res = zig_wrap_i32(full_res, bits);718 *res = zig_wrap_i32(full_res, bits);
...@@ -694,7 +750,7 @@ static inline bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 b...@@ -694,7 +750,7 @@ static inline bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 b
694 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);750 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
695#else751#else
696 zig_c_int overflow_int;752 zig_c_int overflow_int;
697 zig_u64 full_res = __mulodi4(lhs, rhs, &overflow_int);753 zig_i64 full_res = __mulodi4(lhs, rhs, &overflow_int);
698 bool overflow = overflow_int != 0;754 bool overflow = overflow_int != 0;
699#endif755#endif
700 *res = zig_wrap_i64(full_res, bits);756 *res = zig_wrap_i64(full_res, bits);
...@@ -714,7 +770,10 @@ static inline bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits)...@@ -714,7 +770,10 @@ static inline bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits)
714 *res = zig_wrap_u8(full_res, bits);770 *res = zig_wrap_u8(full_res, bits);
715 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);771 return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits);
716#else772#else
717 return zig_mulo_u32(res, lhs, rhs, bits);773 zig_u32 full_res;
774 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
775 *res = (zig_u8)full_res;
776 return overflow;
718#endif777#endif
719}778}
720779
...@@ -731,7 +790,10 @@ static inline bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits)...@@ -731,7 +790,10 @@ static inline bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits)
731 *res = zig_wrap_i8(full_res, bits);790 *res = zig_wrap_i8(full_res, bits);
732 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);791 return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits);
733#else792#else
734 return zig_mulo_i32(res, lhs, rhs, bits);793 zig_i32 full_res;
794 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
795 *res = (zig_i8)full_res;
796 return overflow;
735#endif797#endif
736}798}
737799
...@@ -748,7 +810,10 @@ static inline bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 b...@@ -748,7 +810,10 @@ static inline bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 b
748 *res = zig_wrap_u16(full_res, bits);810 *res = zig_wrap_u16(full_res, bits);
749 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);811 return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits);
750#else812#else
751 return zig_mulo_u32(res, lhs, rhs, bits);813 zig_u32 full_res;
814 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
815 *res = (zig_u16)full_res;
816 return overflow;
752#endif817#endif
753}818}
754819
...@@ -765,7 +830,10 @@ static inline bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 b...@@ -765,7 +830,10 @@ static inline bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 b
765 *res = zig_wrap_i16(full_res, bits);830 *res = zig_wrap_i16(full_res, bits);
766 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);831 return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits);
767#else832#else
768 return zig_mulo_i32(res, lhs, rhs, bits);833 zig_i32 full_res;
834 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
835 *res = (zig_i16)full_res;
836 return overflow;
769#endif837#endif
770}838}
771839
...@@ -776,38 +844,6 @@ static inline void zig_vmulo_i16(zig_u8 *ov, zig_i16 *res, int n,...@@ -776,38 +844,6 @@ static inline void zig_vmulo_i16(zig_u8 *ov, zig_i16 *res, int n,
776}844}
777845
778#define zig_int_builtins(w) \846#define zig_int_builtins(w) \
779 static inline zig_u##w zig_shlw_u##w(zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \
780 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \
781 } \
782\
783 static inline zig_i##w zig_shlw_i##w(zig_i##w lhs, zig_u8 rhs, zig_u8 bits) { \
784 return zig_wrap_i##w((zig_i##w)zig_shl_u##w((zig_u##w)lhs, (zig_u##w)rhs), bits); \
785 } \
786\
787 static inline zig_u##w zig_addw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
788 return zig_wrap_u##w(lhs + rhs, bits); \
789 } \
790\
791 static inline zig_i##w zig_addw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
792 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs + (zig_u##w)rhs), bits); \
793 } \
794\
795 static inline zig_u##w zig_subw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
796 return zig_wrap_u##w(lhs - rhs, bits); \
797 } \
798\
799 static inline zig_i##w zig_subw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
800 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs - (zig_u##w)rhs), bits); \
801 } \
802\
803 static inline zig_u##w zig_mulw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \
804 return zig_wrap_u##w(lhs * rhs, bits); \
805 } \
806\
807 static inline zig_i##w zig_mulw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \
808 return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs * (zig_u##w)rhs), bits); \
809 } \
810\
811 static inline bool zig_shlo_u##w(zig_u##w *res, zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \847 static inline bool zig_shlo_u##w(zig_u##w *res, zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \
812 *res = zig_shlw_u##w(lhs, rhs, bits); \848 *res = zig_shlw_u##w(lhs, rhs, bits); \
813 return lhs > zig_maxInt(u##w, bits) >> rhs; \849 return lhs > zig_maxInt(u##w, bits) >> rhs; \
...@@ -893,55 +929,6 @@ typedef zig_c_ulong zig_Builtin64;...@@ -893,55 +929,6 @@ typedef zig_c_ulong zig_Builtin64;
893typedef zig_c_ulonglong zig_Builtin64;929typedef zig_c_ulonglong zig_Builtin64;
894#endif930#endif
895931
896#if zig_has_builtin(clz)
897#define zig_builtin_clz(w) \
898 static inline zig_u8 zig_clz_u##w(zig_u##w val, zig_u8 bits) { \
899 if (val == 0) return bits; \
900 return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
901 } \
902\
903 static inline zig_u8 zig_clz_i##w(zig_i##w val, zig_u8 bits) { \
904 return zig_clz_u##w((zig_u##w)val, bits); \
905 }
906zig_builtin_clz(8)
907zig_builtin_clz(16)
908zig_builtin_clz(32)
909zig_builtin_clz(64)
910#endif
911
912#if zig_has_builtin(ctz)
913#define zig_builtin_ctz(w) \
914 static inline zig_u8 zig_ctz_u##w(zig_u##w val, zig_u8 bits) { \
915 if (val == 0) return bits; \
916 return zig_builtin##w(ctz, val); \
917 } \
918\
919 static inline zig_u8 zig_ctz_i##w(zig_i##w val, zig_u8 bits) { \
920 return zig_ctz_u##w((zig_u##w)val, bits); \
921 }
922zig_builtin_ctz(8)
923zig_builtin_ctz(16)
924zig_builtin_ctz(32)
925zig_builtin_ctz(64)
926#endif
927
928#if zig_has_builtin(popcount)
929#define zig_builtin_popcount(w) \
930 static inline zig_u8 zig_popcount_u##w(zig_u##w val, zig_u8 bits) { \
931 (void)bits; \
932 return zig_builtin##w(popcount, val); \
933 } \
934\
935 static inline zig_u8 zig_popcount_i##w(zig_i##w val, zig_u8 bits) { \
936 \
937 return zig_popcount_u##w((zig_u##w)val, bits); \
938 }
939zig_builtin_popcount(8)
940zig_builtin_popcount(16)
941zig_builtin_popcount(32)
942zig_builtin_popcount(64)
943#endif
944
945static inline zig_u8 zig_byte_swap_u8(zig_u8 val, zig_u8 bits) {932static inline zig_u8 zig_byte_swap_u8(zig_u8 val, zig_u8 bits) {
946 return zig_wrap_u8(val >> (8 - bits), bits);933 return zig_wrap_u8(val >> (8 - bits), bits);
947}934}
...@@ -955,8 +942,8 @@ static inline zig_u16 zig_byte_swap_u16(zig_u16 val, zig_u8 bits) {...@@ -955,8 +942,8 @@ static inline zig_u16 zig_byte_swap_u16(zig_u16 val, zig_u8 bits) {
955#if zig_has_builtin(bswap16)942#if zig_has_builtin(bswap16)
956 full_res = __builtin_bswap16(val);943 full_res = __builtin_bswap16(val);
957#else944#else
958 full_res = (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 0)) << 8 |945 full_res = (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 0), 8) << 8 |
959 (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 8)) >> 0;946 (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 8), 8) >> 0;
960#endif947#endif
961 return zig_wrap_u16(full_res >> (16 - bits), bits);948 return zig_wrap_u16(full_res >> (16 - bits), bits);
962}949}
...@@ -970,8 +957,8 @@ static inline zig_u32 zig_byte_swap_u32(zig_u32 val, zig_u8 bits) {...@@ -970,8 +957,8 @@ static inline zig_u32 zig_byte_swap_u32(zig_u32 val, zig_u8 bits) {
970#if zig_has_builtin(bswap32)957#if zig_has_builtin(bswap32)
971 full_res = __builtin_bswap32(val);958 full_res = __builtin_bswap32(val);
972#else959#else
973 full_res = (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 0)) << 16 |960 full_res = (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 0), 16) << 16 |
974 (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 16)) >> 0;961 (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 16), 16) >> 0;
975#endif962#endif
976 return zig_wrap_u32(full_res >> (32 - bits), bits);963 return zig_wrap_u32(full_res >> (32 - bits), bits);
977}964}
...@@ -985,8 +972,8 @@ static inline zig_u64 zig_byte_swap_u64(zig_u64 val, zig_u8 bits) {...@@ -985,8 +972,8 @@ static inline zig_u64 zig_byte_swap_u64(zig_u64 val, zig_u8 bits) {
985#if zig_has_builtin(bswap64)972#if zig_has_builtin(bswap64)
986 full_res = __builtin_bswap64(val);973 full_res = __builtin_bswap64(val);
987#else974#else
988 full_res = (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 0)) << 32 |975 full_res = (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 0), 32) << 32 |
989 (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 32)) >> 0;976 (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 32), 32) >> 0;
990#endif977#endif
991 return zig_wrap_u64(full_res >> (64 - bits), bits);978 return zig_wrap_u64(full_res >> (64 - bits), bits);
992}979}
...@@ -1058,6 +1045,85 @@ static inline zig_i64 zig_bit_reverse_i64(zig_i64 val, zig_u8 bits) {...@@ -1058,6 +1045,85 @@ static inline zig_i64 zig_bit_reverse_i64(zig_i64 val, zig_u8 bits) {
1058 return zig_wrap_i64((zig_i64)zig_bit_reverse_u64((zig_u64)val, bits), bits);1045 return zig_wrap_i64((zig_i64)zig_bit_reverse_u64((zig_u64)val, bits), bits);
1059}1046}
10601047
1048#define zig_builtin_popcount_common(w) \
1049 static inline zig_u8 zig_popcount_i##w(zig_i##w val, zig_u8 bits) { \
1050 return zig_popcount_u##w((zig_u##w)val, bits); \
1051 }
1052#if zig_has_builtin(popcount)
1053#define zig_builtin_popcount(w) \
1054 static inline zig_u8 zig_popcount_u##w(zig_u##w val, zig_u8 bits) { \
1055 (void)bits; \
1056 return zig_builtin##w(popcount, val); \
1057 } \
1058\
1059 zig_builtin_popcount_common(w)
1060#else
1061#define zig_builtin_popcount(w) \
1062 static inline zig_u8 zig_popcount_u##w(zig_u##w val, zig_u8 bits) { \
1063 (void)bits; \
1064 zig_u##w temp = val - ((val >> 1) & (zig_maxInt_u##w / 3)); \
1065 temp = (temp & (zig_maxInt_u##w / 5)) + ((temp >> 2) & (zig_maxInt_u##w / 5)); \
1066 temp = (temp + (temp >> 4)) & (zig_maxInt_u##w / 17); \
1067 return temp * (zig_maxInt_u##w / 255) >> (w - 8); \
1068 } \
1069\
1070 zig_builtin_popcount_common(w)
1071#endif
1072zig_builtin_popcount(8)
1073zig_builtin_popcount(16)
1074zig_builtin_popcount(32)
1075zig_builtin_popcount(64)
1076
1077#define zig_builtin_ctz_common(w) \
1078 static inline zig_u8 zig_ctz_i##w(zig_i##w val, zig_u8 bits) { \
1079 return zig_ctz_u##w((zig_u##w)val, bits); \
1080 }
1081#if zig_has_builtin(ctz)
1082#define zig_builtin_ctz(w) \
1083 static inline zig_u8 zig_ctz_u##w(zig_u##w val, zig_u8 bits) { \
1084 if (val == 0) return bits; \
1085 return zig_builtin##w(ctz, val); \
1086 } \
1087\
1088 zig_builtin_ctz_common(w)
1089#else
1090#define zig_builtin_ctz(w) \
1091 static inline zig_u8 zig_ctz_u##w(zig_u##w val, zig_u8 bits) { \
1092 return zig_popcount_u##w(zig_not_u##w(val, bits) & zig_subw_u##w(val, 1, bits), bits); \
1093 } \
1094\
1095 zig_builtin_ctz_common(w)
1096#endif
1097zig_builtin_ctz(8)
1098zig_builtin_ctz(16)
1099zig_builtin_ctz(32)
1100zig_builtin_ctz(64)
1101
1102#define zig_builtin_clz_common(w) \
1103 static inline zig_u8 zig_clz_i##w(zig_i##w val, zig_u8 bits) { \
1104 return zig_clz_u##w((zig_u##w)val, bits); \
1105 }
1106#if zig_has_builtin(clz)
1107#define zig_builtin_clz(w) \
1108 static inline zig_u8 zig_clz_u##w(zig_u##w val, zig_u8 bits) { \
1109 if (val == 0) return bits; \
1110 return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
1111 } \
1112\
1113 zig_builtin_clz_common(w)
1114#else
1115#define zig_builtin_clz(w) \
1116 static inline zig_u8 zig_clz_u##w(zig_u##w val, zig_u8 bits) { \
1117 return zig_ctz_u##w(zig_bit_reverse_u##w(val, bits), bits); \
1118 } \
1119\
1120 zig_builtin_clz_common(w)
1121#endif
1122zig_builtin_clz(8)
1123zig_builtin_clz(16)
1124zig_builtin_clz(32)
1125zig_builtin_clz(64)
1126
1061/* ======================== 128-bit Integer Routines ======================== */1127/* ======================== 128-bit Integer Routines ======================== */
10621128
1063#if !defined(zig_has_int128)1129#if !defined(zig_has_int128)
...@@ -1421,7 +1487,7 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_...@@ -1421,7 +1487,7 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_
1421 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);1487 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1422#else1488#else
1423 zig_c_int overflow_int;1489 zig_c_int overflow_int;
1424 zig_i128 full_res = __muloti4(lhs, rhs, &overflow);1490 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
1425 bool overflow = overflow_int != 0;1491 bool overflow = overflow_int != 0;
1426#endif1492#endif
1427 *res = zig_wrap_i128(full_res, bits);1493 *res = zig_wrap_i128(full_res, bits);