authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-03 00:18:35-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-05 02:59:01-05:00
loga8f4ac2b94e7945a5a1623547f258f5f32f12674
tree9df07c2806ddb646e80eda653bee7865439955f3
parent874ae81f1b2ae76cea6f5c79203f4baa68263163

CBE: implement big integer and vector comparisons


7 files changed, 595 insertions(+), 191 deletions(-)

lib/zig.h+254-59
...@@ -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__)
...@@ -1379,7 +1387,7 @@ typedef signed __int128 zig_i128;...@@ -1379,7 +1387,7 @@ typedef signed __int128 zig_i128;
13791387
1380#else /* zig_has_int128 */1388#else /* zig_has_int128 */
13811389
1382#if __LITTLE_ENDIAN__ || _MSC_VER1390#if zig_little_endian
1383typedef struct { zig_align(16) uint64_t lo; uint64_t hi; } zig_u128;1391typedef 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;1392typedef struct { zig_align(16) uint64_t lo; int64_t hi; } zig_i128;
1385#else1393#else
...@@ -1909,6 +1917,177 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {...@@ -1909,6 +1917,177 @@ 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));1917 return zig_bitcast_i128(zig_bit_reverse_u128(zig_bitcast_u128(val), bits));
1910}1918}
19111919
1920/* ========================== Big Integer Support =========================== */
1921
1922static inline uint16_t zig_big_bytes(uint16_t bits) {
1923 uint16_t bytes = (bits + CHAR_BIT - 1) / CHAR_BIT;
1924 uint16_t alignment = 16;
1925 while (alignment / 2 >= bytes) alignment /= 2;
1926 return (bytes + alignment - 1) / alignment * alignment;
1927}
1928
1929static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
1930 const uint8_t *lhs_bytes = lhs;
1931 const uint8_t *rhs_bytes = rhs;
1932 uint16_t byte_offset = 0;
1933 bool do_signed = is_signed;
1934 uint16_t remaining_bytes = zig_big_bytes(bits);
1935
1936#if zig_little_endian
1937 byte_offset = remaining_bytes;
1938#endif
1939
1940 while (remaining_bytes >= 128 / CHAR_BIT) {
1941 int32_t limb_cmp;
1942
1943#if zig_little_endian
1944 byte_offset -= 128 / CHAR_BIT;
1945#endif
1946
1947 if (do_signed) {
1948 zig_i128 lhs_limb;
1949 zig_i128 rhs_limb;
1950
1951 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1952 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1953 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
1954 do_signed = false;
1955 } else {
1956 zig_u128 lhs_limb;
1957 zig_u128 rhs_limb;
1958
1959 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1960 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1961 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
1962 }
1963
1964 if (limb_cmp != 0) return limb_cmp;
1965 remaining_bytes -= 128 / CHAR_BIT;
1966
1967#if zig_big_endian
1968 byte_offset -= 128 / CHAR_BIT;
1969#endif
1970 }
1971
1972 while (remaining_bytes >= 64 / CHAR_BIT) {
1973#if zig_little_endian
1974 byte_offset -= 64 / CHAR_BIT;
1975#endif
1976
1977 if (do_signed) {
1978 int64_t lhs_limb;
1979 int64_t rhs_limb;
1980
1981 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1982 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1983 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
1984 do_signed = false;
1985 } else {
1986 uint64_t lhs_limb;
1987 uint64_t rhs_limb;
1988
1989 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
1990 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
1991 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
1992 }
1993
1994 remaining_bytes -= 64 / CHAR_BIT;
1995
1996#if zig_big_endian
1997 byte_offset -= 64 / CHAR_BIT;
1998#endif
1999 }
2000
2001 while (remaining_bytes >= 32 / CHAR_BIT) {
2002#if zig_little_endian
2003 byte_offset -= 32 / CHAR_BIT;
2004#endif
2005
2006 if (do_signed) {
2007 int32_t lhs_limb;
2008 int32_t rhs_limb;
2009
2010 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2011 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2012 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2013 do_signed = false;
2014 } else {
2015 uint32_t lhs_limb;
2016 uint32_t rhs_limb;
2017
2018 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2019 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2020 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2021 }
2022
2023 remaining_bytes -= 32 / CHAR_BIT;
2024
2025#if zig_big_endian
2026 byte_offset -= 32 / CHAR_BIT;
2027#endif
2028 }
2029
2030 while (remaining_bytes >= 16 / CHAR_BIT) {
2031#if zig_little_endian
2032 byte_offset -= 16 / CHAR_BIT;
2033#endif
2034
2035 if (do_signed) {
2036 int16_t lhs_limb;
2037 int16_t rhs_limb;
2038
2039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2040 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2041 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2042 do_signed = false;
2043 } else {
2044 uint16_t lhs_limb;
2045 uint16_t rhs_limb;
2046
2047 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2048 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2049 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2050 }
2051
2052 remaining_bytes -= 16 / CHAR_BIT;
2053
2054#if zig_big_endian
2055 byte_offset -= 16 / CHAR_BIT;
2056#endif
2057 }
2058
2059 while (remaining_bytes >= 8 / CHAR_BIT) {
2060#if zig_little_endian
2061 byte_offset -= 8 / CHAR_BIT;
2062#endif
2063
2064 if (do_signed) {
2065 int8_t lhs_limb;
2066 int8_t rhs_limb;
2067
2068 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2069 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2070 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2071 do_signed = false;
2072 } else {
2073 uint8_t lhs_limb;
2074 uint8_t rhs_limb;
2075
2076 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
2077 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
2078 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
2079 }
2080
2081 remaining_bytes -= 8 / CHAR_BIT;
2082
2083#if zig_big_endian
2084 byte_offset -= 8 / CHAR_BIT;
2085#endif
2086 }
2087
2088 return 0;
2089}
2090
1912/* ========================= Floating Point Support ========================= */2091/* ========================= Floating Point Support ========================= */
19132092
1914#if _MSC_VER2093#if _MSC_VER
...@@ -1933,7 +2112,6 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {...@@ -1933,7 +2112,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)2112#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)2113#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)2114#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#else2115#else
1938#define zig_has_float_builtins 02116#define zig_has_float_builtins 0
1939#define zig_make_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr)2117#define zig_make_special_f16(sign, name, arg, repr) zig_float_from_repr_f16(repr)
...@@ -1941,13 +2119,13 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) {...@@ -1941,13 +2119,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)2119#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)2120#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)2121#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#endif2122#endif
19462123
1947#define zig_has_f16 12124#define zig_has_f16 1
1948#define zig_bitSizeOf_f16 162125#define zig_bitSizeOf_f16 16
2126typedef int16_t zig_repr_f16;
1949#define zig_libc_name_f16(name) __##name##h2127#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)2128#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
1951#if FLT_MANT_DIG == 112129#if FLT_MANT_DIG == 11
1952typedef float zig_f16;2130typedef float zig_f16;
1953#define zig_make_f16(fp, repr) fp##f2131#define zig_make_f16(fp, repr) fp##f
...@@ -1956,7 +2134,9 @@ typedef double zig_f16;...@@ -1956,7 +2134,9 @@ typedef double zig_f16;
1956#define zig_make_f16(fp, repr) fp2134#define zig_make_f16(fp, repr) fp
1957#elif LDBL_MANT_DIG == 112135#elif LDBL_MANT_DIG == 11
1958#define zig_bitSizeOf_c_longdouble 162136#define zig_bitSizeOf_c_longdouble 16
1959typedef uint16_t zig_repr_c_longdouble;2137#ifndef ZIG_TARGET_ABI_MSVC
2138typedef zig_repr_f16 zig_repr_c_longdouble;
2139#endif
1960typedef long double zig_f16;2140typedef long double zig_f16;
1961#define zig_make_f16(fp, repr) fp##l2141#define zig_make_f16(fp, repr) fp##l
1962#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))2142#elif FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gnuc))
...@@ -1973,17 +2153,18 @@ typedef int16_t zig_f16;...@@ -1973,17 +2153,18 @@ typedef int16_t zig_f16;
1973#define zig_make_f16(fp, repr) repr2153#define zig_make_f16(fp, repr) repr
1974#undef zig_make_special_f162154#undef zig_make_special_f16
1975#define zig_make_special_f16(sign, name, arg, repr) repr2155#define zig_make_special_f16(sign, name, arg, repr) repr
1976#undef zig_make_special_constant_f162156#undef zig_init_special_f16
1977#define zig_make_special_constant_f16(sign, name, arg, repr) repr2157#define zig_init_special_f16(sign, name, arg, repr) repr
1978#endif2158#endif
19792159
1980#define zig_has_f32 12160#define zig_has_f32 1
1981#define zig_bitSizeOf_f32 322161#define zig_bitSizeOf_f32 32
2162typedef int32_t zig_repr_f32;
1982#define zig_libc_name_f32(name) name##f2163#define zig_libc_name_f32(name) name##f
1983#if _MSC_VER2164#if _MSC_VER
1984#define zig_make_special_constant_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, )2165#define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, )
1985#else2166#else
1986#define zig_make_special_constant_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)2167#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)
1987#endif2168#endif
1988#if FLT_MANT_DIG == 242169#if FLT_MANT_DIG == 24
1989typedef float zig_f32;2170typedef float zig_f32;
...@@ -1993,7 +2174,9 @@ typedef double zig_f32;...@@ -1993,7 +2174,9 @@ typedef double zig_f32;
1993#define zig_make_f32(fp, repr) fp2174#define zig_make_f32(fp, repr) fp
1994#elif LDBL_MANT_DIG == 242175#elif LDBL_MANT_DIG == 24
1995#define zig_bitSizeOf_c_longdouble 322176#define zig_bitSizeOf_c_longdouble 32
1996typedef uint32_t zig_repr_c_longdouble;2177#ifndef ZIG_TARGET_ABI_MSVC
2178typedef zig_repr_f32 zig_repr_c_longdouble;
2179#endif
1997typedef long double zig_f32;2180typedef long double zig_f32;
1998#define zig_make_f32(fp, repr) fp##l2181#define zig_make_f32(fp, repr) fp##l
1999#elif FLT32_MANT_DIG == 242182#elif FLT32_MANT_DIG == 24
...@@ -2007,21 +2190,24 @@ typedef int32_t zig_f32;...@@ -2007,21 +2190,24 @@ typedef int32_t zig_f32;
2007#define zig_make_f32(fp, repr) repr2190#define zig_make_f32(fp, repr) repr
2008#undef zig_make_special_f322191#undef zig_make_special_f32
2009#define zig_make_special_f32(sign, name, arg, repr) repr2192#define zig_make_special_f32(sign, name, arg, repr) repr
2010#undef zig_make_special_constant_f322193#undef zig_init_special_f32
2011#define zig_make_special_constant_f32(sign, name, arg, repr) repr2194#define zig_init_special_f32(sign, name, arg, repr) repr
2012#endif2195#endif
20132196
2014#define zig_has_f64 12197#define zig_has_f64 1
2015#define zig_bitSizeOf_f64 642198#define zig_bitSizeOf_f64 64
2199typedef int64_t zig_repr_f64;
2016#define zig_libc_name_f64(name) name2200#define zig_libc_name_f64(name) name
2017#if _MSC_VER2201#if _MSC_VER
2018#ifdef ZIG_TARGET_ABI_MSVC2202#ifdef ZIG_TARGET_ABI_MSVC
2019#define zig_bitSizeOf_c_longdouble 642203#define zig_bitSizeOf_c_longdouble 64
2020typedef uint64_t zig_repr_c_longdouble;2204#ifndef ZIG_TARGET_ABI_MSVC
2205typedef zig_repr_f64 zig_repr_c_longdouble;
2206#endif
2021#endif2207#endif
2022#define zig_make_special_constant_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )2208#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
2023#else /* _MSC_VER */2209#else /* _MSC_VER */
2024#define zig_make_special_constant_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)2210#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
2025#endif /* _MSC_VER */2211#endif /* _MSC_VER */
2026#if FLT_MANT_DIG == 532212#if FLT_MANT_DIG == 53
2027typedef float zig_f64;2213typedef float zig_f64;
...@@ -2031,7 +2217,9 @@ typedef double zig_f64;...@@ -2031,7 +2217,9 @@ typedef double zig_f64;
2031#define zig_make_f64(fp, repr) fp2217#define zig_make_f64(fp, repr) fp
2032#elif LDBL_MANT_DIG == 532218#elif LDBL_MANT_DIG == 53
2033#define zig_bitSizeOf_c_longdouble 642219#define zig_bitSizeOf_c_longdouble 64
2034typedef uint64_t zig_repr_c_longdouble;2220#ifndef ZIG_TARGET_ABI_MSVC
2221typedef zig_repr_f64 zig_repr_c_longdouble;
2222#endif
2035typedef long double zig_f64;2223typedef long double zig_f64;
2036#define zig_make_f64(fp, repr) fp##l2224#define zig_make_f64(fp, repr) fp##l
2037#elif FLT64_MANT_DIG == 532225#elif FLT64_MANT_DIG == 53
...@@ -2048,14 +2236,15 @@ typedef int64_t zig_f64;...@@ -2048,14 +2236,15 @@ typedef int64_t zig_f64;
2048#define zig_make_f64(fp, repr) repr2236#define zig_make_f64(fp, repr) repr
2049#undef zig_make_special_f642237#undef zig_make_special_f64
2050#define zig_make_special_f64(sign, name, arg, repr) repr2238#define zig_make_special_f64(sign, name, arg, repr) repr
2051#undef zig_make_special_constant_f642239#undef zig_init_special_f64
2052#define zig_make_special_constant_f64(sign, name, arg, repr) repr2240#define zig_init_special_f64(sign, name, arg, repr) repr
2053#endif2241#endif
20542242
2055#define zig_has_f80 12243#define zig_has_f80 1
2056#define zig_bitSizeOf_f80 802244#define zig_bitSizeOf_f80 80
2245typedef zig_i128 zig_repr_f80;
2057#define zig_libc_name_f80(name) __##name##x2246#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)2247#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
2059#if FLT_MANT_DIG == 642248#if FLT_MANT_DIG == 64
2060typedef float zig_f80;2249typedef float zig_f80;
2061#define zig_make_f80(fp, repr) fp##f2250#define zig_make_f80(fp, repr) fp##f
...@@ -2064,7 +2253,9 @@ typedef double zig_f80;...@@ -2064,7 +2253,9 @@ typedef double zig_f80;
2064#define zig_make_f80(fp, repr) fp2253#define zig_make_f80(fp, repr) fp
2065#elif LDBL_MANT_DIG == 642254#elif LDBL_MANT_DIG == 64
2066#define zig_bitSizeOf_c_longdouble 802255#define zig_bitSizeOf_c_longdouble 80
2067typedef zig_u128 zig_repr_c_longdouble;2256#ifndef ZIG_TARGET_ABI_MSVC
2257typedef zig_repr_f80 zig_repr_c_longdouble;
2258#endif
2068typedef long double zig_f80;2259typedef long double zig_f80;
2069#define zig_make_f80(fp, repr) fp##l2260#define zig_make_f80(fp, repr) fp##l
2070#elif FLT80_MANT_DIG == 642261#elif FLT80_MANT_DIG == 64
...@@ -2084,14 +2275,15 @@ typedef zig_i128 zig_f80;...@@ -2084,14 +2275,15 @@ typedef zig_i128 zig_f80;
2084#define zig_make_f80(fp, repr) repr2275#define zig_make_f80(fp, repr) repr
2085#undef zig_make_special_f802276#undef zig_make_special_f80
2086#define zig_make_special_f80(sign, name, arg, repr) repr2277#define zig_make_special_f80(sign, name, arg, repr) repr
2087#undef zig_make_special_constant_f802278#undef zig_init_special_f80
2088#define zig_make_special_constant_f80(sign, name, arg, repr) repr2279#define zig_init_special_f80(sign, name, arg, repr) repr
2089#endif2280#endif
20902281
2091#define zig_has_f128 12282#define zig_has_f128 1
2092#define zig_bitSizeOf_f128 1282283#define zig_bitSizeOf_f128 128
2284typedef zig_i128 zig_repr_f128;
2093#define zig_libc_name_f128(name) name##q2285#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)2286#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
2095#if FLT_MANT_DIG == 1132287#if FLT_MANT_DIG == 113
2096typedef float zig_f128;2288typedef float zig_f128;
2097#define zig_make_f128(fp, repr) fp##f2289#define zig_make_f128(fp, repr) fp##f
...@@ -2100,7 +2292,9 @@ typedef double zig_f128;...@@ -2100,7 +2292,9 @@ typedef double zig_f128;
2100#define zig_make_f128(fp, repr) fp2292#define zig_make_f128(fp, repr) fp
2101#elif LDBL_MANT_DIG == 1132293#elif LDBL_MANT_DIG == 113
2102#define zig_bitSizeOf_c_longdouble 1282294#define zig_bitSizeOf_c_longdouble 128
2103typedef zig_u128 zig_repr_c_longdouble;2295#ifndef ZIG_TARGET_ABI_MSVC
2296typedef zig_repr_f128 zig_repr_c_longdouble;
2297#endif
2104typedef long double zig_f128;2298typedef long double zig_f128;
2105#define zig_make_f128(fp, repr) fp##l2299#define zig_make_f128(fp, repr) fp##l
2106#elif FLT128_MANT_DIG == 1132300#elif FLT128_MANT_DIG == 113
...@@ -2122,63 +2316,44 @@ typedef zig_i128 zig_f128;...@@ -2122,63 +2316,44 @@ typedef zig_i128 zig_f128;
2122#define zig_make_f128(fp, repr) repr2316#define zig_make_f128(fp, repr) repr
2123#undef zig_make_special_f1282317#undef zig_make_special_f128
2124#define zig_make_special_f128(sign, name, arg, repr) repr2318#define zig_make_special_f128(sign, name, arg, repr) repr
2125#undef zig_make_special_constant_f1282319#undef zig_init_special_f128
2126#define zig_make_special_constant_f128(sign, name, arg, repr) repr2320#define zig_init_special_f128(sign, name, arg, repr) repr
2127#endif2321#endif
21282322
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_longdouble2323#ifdef zig_bitSizeOf_c_longdouble
21392324
2325#define zig_has_c_longdouble 1
2140#ifdef ZIG_TARGET_ABI_MSVC2326#ifdef ZIG_TARGET_ABI_MSVC
2141#undef zig_bitSizeOf_c_longdouble2327#undef zig_bitSizeOf_c_longdouble
2142#define zig_bitSizeOf_c_longdouble 642328#define zig_bitSizeOf_c_longdouble 64
2143typedef uint64_t zig_repr_c_longdouble;
2144typedef zig_f64 zig_c_longdouble;2329typedef zig_f64 zig_c_longdouble;
2145#define zig_make_c_longdouble(fp, repr) fp2330typedef zig_repr_f64 zig_repr_c_longdouble;
2146#else2331#else
2147typedef long double zig_c_longdouble;2332typedef long double zig_c_longdouble;
2148#define zig_make_c_longdouble(fp, repr) fp##l
2149#endif2333#endif
21502334
2151#else /* zig_bitSizeOf_c_longdouble */2335#else /* zig_bitSizeOf_c_longdouble */
21522336
2153#undef zig_has_c_longdouble
2154#define zig_has_c_longdouble 02337#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 1282338#define zig_bitSizeOf_repr_c_longdouble 128
2159typedef zig_i128 zig_c_longdouble;2339typedef zig_f128 zig_c_longdouble;
2160#define zig_make_c_longdouble(fp, repr) repr2340typedef 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
21652341
2166#endif /* zig_bitSizeOf_c_longdouble */2342#endif /* zig_bitSizeOf_c_longdouble */
21672343
2168#if !zig_has_float_builtins2344#if !zig_has_float_builtins
2169#define zig_float_from_repr(Type, ReprType) \2345#define zig_float_from_repr(Type) \
2170 static inline zig_##Type zig_float_from_repr_##Type(ReprType repr) { \2346 static inline zig_##Type zig_float_from_repr_##Type(zig_repr_##Type repr) { \
2171 zig_##Type result; \2347 zig_##Type result; \
2172 memcpy(&result, &repr, sizeof(result)); \2348 memcpy(&result, &repr, sizeof(result)); \
2173 return result; \2349 return result; \
2174 }2350 }
21752351
2176zig_float_from_repr(f16, uint16_t)2352zig_float_from_repr(f16)
2177zig_float_from_repr(f32, uint32_t)2353zig_float_from_repr(f32)
2178zig_float_from_repr(f64, uint64_t)2354zig_float_from_repr(f64)
2179zig_float_from_repr(f80, zig_u128)2355zig_float_from_repr(f80)
2180zig_float_from_repr(f128, zig_u128)2356zig_float_from_repr(f128)
2181zig_float_from_repr(c_longdouble, zig_repr_c_longdouble)
2182#endif2357#endif
21832358
2184#define zig_cast_f16 (zig_f16)2359#define zig_cast_f16 (zig_f16)
...@@ -2187,11 +2362,9 @@ zig_float_from_repr(c_longdouble, zig_repr_c_longdouble)...@@ -2187,11 +2362,9 @@ zig_float_from_repr(c_longdouble, zig_repr_c_longdouble)
21872362
2188#if _MSC_VER && !zig_has_f1282363#if _MSC_VER && !zig_has_f128
2189#define zig_cast_f802364#define zig_cast_f80
2190#define zig_cast_c_longdouble
2191#define zig_cast_f1282365#define zig_cast_f128
2192#else2366#else
2193#define zig_cast_f80 (zig_f80)2367#define zig_cast_f80 (zig_f80)
2194#define zig_cast_c_longdouble (zig_c_longdouble)
2195#define zig_cast_f128 (zig_f128)2368#define zig_cast_f128 (zig_f128)
2196#endif2369#endif
21972370
...@@ -2320,7 +2493,6 @@ zig_float_builtins(f32)...@@ -2320,7 +2493,6 @@ zig_float_builtins(f32)
2320zig_float_builtins(f64)2493zig_float_builtins(f64)
2321zig_float_builtins(f80)2494zig_float_builtins(f80)
2322zig_float_builtins(f128)2495zig_float_builtins(f128)
2323zig_float_builtins(c_longdouble)
23242496
2325#if _MSC_VER && (_M_IX86 || _M_X64)2497#if _MSC_VER && (_M_IX86 || _M_X64)
23262498
...@@ -2563,6 +2735,29 @@ zig_msvc_atomics_128op(u128, max)...@@ -2563,6 +2735,29 @@ zig_msvc_atomics_128op(u128, max)
25632735
2564#endif /* _MSC_VER && (_M_IX86 || _M_X64) */2736#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
25652737
2738/* ============================= Vector Support ============================= */
2739
2740#define zig_cmp_vec(operation, operator) \
2741 static inline void zig_##operation##_vec(bool *result, const void *lhs, const void *rhs, uint32_t len, bool is_signed, uint16_t elem_bits) { \
2742 uint32_t index = 0; \
2743 const uint8_t *lhs_ptr = lhs; \
2744 const uint8_t *rhs_ptr = rhs; \
2745 uint16_t elem_bytes = zig_big_bytes(elem_bits); \
2746 \
2747 while (index < len) { \
2748 result[index] = zig_cmp_big(lhs_ptr, rhs_ptr, is_signed, elem_bits) operator 0; \
2749 lhs_ptr += elem_bytes; \
2750 rhs_ptr += elem_bytes; \
2751 index += 1; \
2752 } \
2753 }
2754zig_cmp_vec(eq, ==)
2755zig_cmp_vec(ne, !=)
2756zig_cmp_vec(lt, < )
2757zig_cmp_vec(le, <=)
2758zig_cmp_vec(gt, > )
2759zig_cmp_vec(ge, >=)
2760
2566/* ======================== Special Case Intrinsics ========================= */2761/* ======================== Special Case Intrinsics ========================= */
25672762
2568#if (_MSC_VER && _M_X64) || defined(__x86_64__)2763#if (_MSC_VER && _M_X64) || defined(__x86_64__)
src/codegen/c.zig+216-126
...@@ -112,11 +112,7 @@ const ValueRenderLocation = enum {...@@ -112,11 +112,7 @@ const ValueRenderLocation = enum {
112 }112 }
113};113};
114114
115const BuiltinInfo = enum {115const BuiltinInfo = enum { none, bits };
116 None,
117 Range,
118 Bits,
119};
120116
121const reserved_idents = std.ComptimeStringMap(void, .{117const reserved_idents = std.ComptimeStringMap(void, .{
122 // C language118 // C language
...@@ -440,6 +436,10 @@ pub const Function = struct {...@@ -440,6 +436,10 @@ pub const Function = struct {
440 return f.object.dg.typeToCType(ty, kind);436 return f.object.dg.typeToCType(ty, kind);
441 }437 }
442438
439 fn byteSize(f: *Function, cty: CType) u64 {
440 return f.object.dg.byteSize(cty);
441 }
442
443 fn renderType(f: *Function, w: anytype, t: Type) !void {443 fn renderType(f: *Function, w: anytype, t: Type) !void {
444 return f.object.dg.renderType(w, t);444 return f.object.dg.renderType(w, t);
445 }445 }
...@@ -1003,8 +1003,9 @@ pub const DeclGen = struct {...@@ -1003,8 +1003,9 @@ pub const DeclGen = struct {
1003 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});1003 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});
1004 }1004 }
10051005
1006 try writer.writeAll("zig_make_special_");1006 try writer.writeAll("zig_");
1007 if (location == .StaticInitializer) try writer.writeAll("constant_");1007 try writer.writeAll(if (location == .StaticInitializer) "init" else "make");
1008 try writer.writeAll("_special_");
1008 try dg.renderTypeForBuiltinFnName(writer, ty);1009 try dg.renderTypeForBuiltinFnName(writer, ty);
1009 try writer.writeByte('(');1010 try writer.writeByte('(');
1010 if (std.math.signbit(f128_val)) try writer.writeByte('-');1011 if (std.math.signbit(f128_val)) try writer.writeByte('-');
...@@ -1565,6 +1566,10 @@ pub const DeclGen = struct {...@@ -1565,6 +1566,10 @@ pub const DeclGen = struct {
1565 return dg.ctypes.typeToCType(dg.gpa, ty, dg.module, kind);1566 return dg.ctypes.typeToCType(dg.gpa, ty, dg.module, kind);
1566 }1567 }
15671568
1569 fn byteSize(dg: *DeclGen, cty: CType) u64 {
1570 return cty.byteSize(dg.ctypes.set, dg.module.getTarget());
1571 }
1572
1568 /// Renders a type as a single identifier, generating intermediate typedefs1573 /// Renders a type as a single identifier, generating intermediate typedefs
1569 /// if necessary.1574 /// if necessary.
1570 ///1575 ///
...@@ -1861,51 +1866,64 @@ pub const DeclGen = struct {...@@ -1861,51 +1866,64 @@ pub const DeclGen = struct {
1861 }1866 }
18621867
1863 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {1868 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
1864 const target = dg.module.getTarget();1869 try dg.renderCTypeForBuiltinFnName(writer, try dg.typeToCType(ty, .complete));
1865 if (ty.isAbiInt()) {1870 }
1866 const int_info = ty.intInfo(target);1871
1867 const c_bits = toCIntBits(int_info.bits) orelse1872 fn renderCTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, cty: CType) !void {
1868 return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{});1873 switch (cty.tag()) {
1869 try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits });1874 else => try writer.print("{c}{d}", .{
1870 } else if (ty.isRuntimeFloat()) {1875 if (cty.isBool())
1871 try ty.print(writer, dg.module);1876 signAbbrev(.unsigned)
1872 } else if (ty.isPtrAtRuntime()) {1877 else if (cty.isInteger())
1873 try writer.print("p{d}", .{ty.bitSize(target)});1878 signAbbrev(cty.signedness() orelse .unsigned)
1874 } else if (ty.zigTypeTag() == .Bool) {1879 else if (cty.isFloat())
1875 try writer.print("u8", .{});1880 @as(u8, 'f')
1876 } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{1881 else if (cty.isPointer())
1877 ty.fmt(dg.module),1882 @as(u8, 'p')
1878 });1883 else
1884 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
1885 cty.tag(),
1886 }),
1887 if (cty.isFloat()) cty.floatActiveBits(dg.module.getTarget()) else dg.byteSize(cty) * 8,
1888 }),
1889 .array => try writer.writeAll("big"),
1890 .vector => try writer.writeAll("vec"),
1891 }
1879 }1892 }
18801893
1881 fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {1894 fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {
1882 const target = dg.module.getTarget();
1883 switch (info) {1895 switch (info) {
1884 .None => {},1896 .none => {},
1885 .Range => {1897 .bits => {
1886 var arena = std.heap.ArenaAllocator.init(dg.gpa);1898 const cty = try dg.typeToCType(ty, .complete);
1887 defer arena.deinit();1899 if (cty.castTag(.vector)) |pl| {
18881900 var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = pl.data.len };
1889 const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 };1901 try writer.print(", {}", .{try dg.fmtIntLiteral(
1890 var stack align(@alignOf(ExpectedContents)) =1902 Type.u32,
1891 std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator());1903 Value.initPayload(&len_pl.base),
18921904 .FunctionArgument,
1893 const int_info = ty.intInfo(target);1905 )});
1894 if (int_info.signedness == .signed) {
1895 const min_val = try ty.minInt(stack.get(), target);
1896 try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, min_val, .Other)});
1897 }1906 }
18981907
1899 const max_val = try ty.maxInt(stack.get(), target);1908 const target = dg.module.getTarget();
1900 try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, max_val, .Other)});1909 const elem_ty = ty.shallowElemType();
1901 },1910 const elem_info = if (elem_ty.isAbiInt())
1902 .Bits => {1911 elem_ty.intInfo(target)
1903 var bits_pl = Value.Payload.U64{1912 else
1904 .base = .{ .tag = .int_u64 },1913 std.builtin.Type.Int{
1905 .data = ty.bitSize(target),1914 .signedness = .unsigned,
1906 };1915 .bits = @intCast(u16, elem_ty.bitSize(target)),
1907 const bits_val = Value.initPayload(&bits_pl.base);1916 };
1908 try writer.print(", {}", .{try dg.fmtIntLiteral(Type.u8, bits_val, .Other)});1917 switch (cty.tag()) {
1918 else => {},
1919 .array, .vector => try writer.print(", {}", .{elem_info.signedness == .signed}),
1920 }
1921
1922 var bits_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = elem_info.bits };
1923 try writer.print(", {}", .{try dg.fmtIntLiteral(switch (cty.tag()) {
1924 else => Type.u8,
1925 .array, .vector => Type.u16,
1926 }, Value.initPayload(&bits_pl.base), .FunctionArgument)});
1909 },1927 },
1910 }1928 }
1911 }1929 }
...@@ -2758,35 +2776,35 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -2758,35 +2776,35 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
27582776
2759 // TODO use a different strategy for add, sub, mul, div2777 // TODO use a different strategy for add, sub, mul, div
2760 // that communicates to the optimizer that wrapping is UB.2778 // that communicates to the optimizer that wrapping is UB.
2761 .add => try airBinOp(f, inst, "+", "add", .None),2779 .add => try airBinOp(f, inst, "+", "add", .none),
2762 .sub => try airBinOp(f, inst, "-", "sub", .None),2780 .sub => try airBinOp(f, inst, "-", "sub", .none),
2763 .mul => try airBinOp(f, inst, "*", "mul", .None),2781 .mul => try airBinOp(f, inst, "*", "mul", .none),
27642782
2765 .neg => try airFloatNeg(f, inst),2783 .neg => try airFloatNeg(f, inst),
2766 .div_float => try airBinBuiltinCall(f, inst, "div", .None),2784 .div_float => try airBinBuiltinCall(f, inst, "div", .none),
27672785
2768 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None),2786 .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
2769 .rem => blk: {2787 .rem => blk: {
2770 const bin_op = f.air.instructions.items(.data)[inst].bin_op;2788 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
2771 const lhs_ty = f.air.typeOf(bin_op.lhs);2789 const lhs_ty = f.air.typeOf(bin_op.lhs);
2772 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),2790 // For binary operations @TypeOf(lhs)==@TypeOf(rhs),
2773 // so we only check one.2791 // so we only check one.
2774 break :blk if (lhs_ty.isInt())2792 break :blk if (lhs_ty.isInt())
2775 try airBinOp(f, inst, "%", "rem", .None)2793 try airBinOp(f, inst, "%", "rem", .none)
2776 else2794 else
2777 try airBinFloatOp(f, inst, "fmod");2795 try airBinFloatOp(f, inst, "fmod");
2778 },2796 },
2779 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None),2797 .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .none),
2780 .mod => try airBinBuiltinCall(f, inst, "mod", .None),2798 .mod => try airBinBuiltinCall(f, inst, "mod", .none),
27812799
2782 .addwrap => try airBinBuiltinCall(f, inst, "addw", .Bits),2800 .addwrap => try airBinBuiltinCall(f, inst, "addw", .bits),
2783 .subwrap => try airBinBuiltinCall(f, inst, "subw", .Bits),2801 .subwrap => try airBinBuiltinCall(f, inst, "subw", .bits),
2784 .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .Bits),2802 .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .bits),
27852803
2786 .add_sat => try airBinBuiltinCall(f, inst, "adds", .Bits),2804 .add_sat => try airBinBuiltinCall(f, inst, "adds", .bits),
2787 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .Bits),2805 .sub_sat => try airBinBuiltinCall(f, inst, "subs", .bits),
2788 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits),2806 .mul_sat => try airBinBuiltinCall(f, inst, "muls", .bits),
2789 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits),2807 .shl_sat => try airBinBuiltinCall(f, inst, "shls", .bits),
27902808
2791 .sqrt => try airUnFloatOp(f, inst, "sqrt"),2809 .sqrt => try airUnFloatOp(f, inst, "sqrt"),
2792 .sin => try airUnFloatOp(f, inst, "sin"),2810 .sin => try airUnFloatOp(f, inst, "sin"),
...@@ -2805,34 +2823,38 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -2805,34 +2823,38 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
28052823
2806 .mul_add => try airMulAdd(f, inst),2824 .mul_add => try airMulAdd(f, inst),
28072825
2808 .add_with_overflow => try airOverflow(f, inst, "add", .Bits),2826 .add_with_overflow => try airOverflow(f, inst, "add", .bits),
2809 .sub_with_overflow => try airOverflow(f, inst, "sub", .Bits),2827 .sub_with_overflow => try airOverflow(f, inst, "sub", .bits),
2810 .mul_with_overflow => try airOverflow(f, inst, "mul", .Bits),2828 .mul_with_overflow => try airOverflow(f, inst, "mul", .bits),
2811 .shl_with_overflow => try airOverflow(f, inst, "shl", .Bits),2829 .shl_with_overflow => try airOverflow(f, inst, "shl", .bits),
28122830
2813 .min => try airMinMax(f, inst, '<', "fmin"),2831 .min => try airMinMax(f, inst, '<', "fmin"),
2814 .max => try airMinMax(f, inst, '>', "fmax"),2832 .max => try airMinMax(f, inst, '>', "fmax"),
28152833
2816 .slice => try airSlice(f, inst),2834 .slice => try airSlice(f, inst),
28172835
2818 .cmp_gt => try airCmpOp(f, inst, ">", "gt"),2836 .cmp_gt => try airCmpOp(f, inst, .gt),
2819 .cmp_gte => try airCmpOp(f, inst, ">=", "ge"),2837 .cmp_gte => try airCmpOp(f, inst, .gte),
2820 .cmp_lt => try airCmpOp(f, inst, "<", "lt"),2838 .cmp_lt => try airCmpOp(f, inst, .lt),
2821 .cmp_lte => try airCmpOp(f, inst, "<=", "le"),2839 .cmp_lte => try airCmpOp(f, inst, .lte),
28222840
2823 .cmp_eq => try airEquality(f, inst, "((", "==", "eq"),2841 .cmp_eq => try airEquality(f, inst, .eq),
2824 .cmp_neq => try airEquality(f, inst, "!((", "!=", "ne"),2842 .cmp_neq => try airEquality(f, inst, .neq),
28252843
2826 .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}),2844 .cmp_vector => blk: {
2845 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
2846 const extra = f.air.extraData(Air.VectorCmp, ty_pl.payload).data;
2847 break :blk try cmpBuiltinCall(f, inst, extra, extra.compareOperator(), .operator, .bits);
2848 },
2827 .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst),2849 .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst),
28282850
2829 // bool_and and bool_or are non-short-circuit operations2851 // bool_and and bool_or are non-short-circuit operations
2830 .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .None),2852 .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .none),
2831 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None),2853 .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .none),
2832 .xor => try airBinOp(f, inst, "^", "xor", .None),2854 .xor => try airBinOp(f, inst, "^", "xor", .none),
2833 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None),2855 .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .none),
2834 .shl, => try airBinBuiltinCall(f, inst, "shlw", .Bits),2856 .shl, => try airBinBuiltinCall(f, inst, "shlw", .bits),
2835 .shl_exact => try airBinOp(f, inst, "<<", "shl", .None),2857 .shl_exact => try airBinOp(f, inst, "<<", "shl", .none),
2836 .not => try airNot (f, inst),2858 .not => try airNot (f, inst),
28372859
2838 .optional_payload => try airOptionalPayload(f, inst),2860 .optional_payload => try airOptionalPayload(f, inst),
...@@ -2877,11 +2899,11 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -2877,11 +2899,11 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
2877 .memcpy => try airMemcpy(f, inst),2899 .memcpy => try airMemcpy(f, inst),
2878 .set_union_tag => try airSetUnionTag(f, inst),2900 .set_union_tag => try airSetUnionTag(f, inst),
2879 .get_union_tag => try airGetUnionTag(f, inst),2901 .get_union_tag => try airGetUnionTag(f, inst),
2880 .clz => try airUnBuiltinCall(f, inst, "clz", .Bits),2902 .clz => try airUnBuiltinCall(f, inst, "clz", .bits),
2881 .ctz => try airUnBuiltinCall(f, inst, "ctz", .Bits),2903 .ctz => try airUnBuiltinCall(f, inst, "ctz", .bits),
2882 .popcount => try airUnBuiltinCall(f, inst, "popcount", .Bits),2904 .popcount => try airUnBuiltinCall(f, inst, "popcount", .bits),
2883 .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .Bits),2905 .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .bits),
2884 .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .Bits),2906 .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .bits),
2885 .tag_name => try airTagName(f, inst),2907 .tag_name => try airTagName(f, inst),
2886 .error_name => try airErrorName(f, inst),2908 .error_name => try airErrorName(f, inst),
2887 .splat => try airSplat(f, inst),2909 .splat => try airSplat(f, inst),
...@@ -3349,7 +3371,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3349,7 +3371,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3349 try f.writeCValueDeref(writer, operand);3371 try f.writeCValueDeref(writer, operand);
3350 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});3372 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)});
3351 if (cant_cast) try writer.writeByte(')');3373 if (cant_cast) try writer.writeByte(')');
3352 try f.object.dg.renderBuiltinInfo(writer, field_ty, .Bits);3374 try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits);
3353 try writer.writeByte(')');3375 try writer.writeByte(')');
3354 } else {3376 } else {
3355 try f.writeCValue(writer, local, .Other);3377 try f.writeCValue(writer, local, .Other);
...@@ -3744,7 +3766,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3744,7 +3766,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3744fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {3766fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
3745 const inst_ty = f.air.typeOfIndex(inst);3767 const inst_ty = f.air.typeOfIndex(inst);
3746 if (inst_ty.tag() != .bool)3768 if (inst_ty.tag() != .bool)
3747 return try airUnBuiltinCall(f, inst, "not", .Bits);3769 return try airUnBuiltinCall(f, inst, "not", .bits);
37483770
3749 const ty_op = f.air.instructions.items(.data)[inst].ty_op;3771 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
37503772
...@@ -3803,7 +3825,7 @@ fn airBinOp(...@@ -3803,7 +3825,7 @@ fn airBinOp(
3803 return local;3825 return local;
3804}3826}
38053827
3806fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation: []const u8) !CValue {3828fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: std.math.CompareOperator) !CValue {
3807 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3829 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
38083830
3809 if (f.liveness.isUnused(inst)) {3831 if (f.liveness.isUnused(inst)) {
...@@ -3813,10 +3835,11 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation:...@@ -3813,10 +3835,11 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation:
38133835
3814 const operand_ty = f.air.typeOf(bin_op.lhs);3836 const operand_ty = f.air.typeOf(bin_op.lhs);
3815 const target = f.object.dg.module.getTarget();3837 const target = f.object.dg.module.getTarget();
3816 if (operand_ty.isInt() and operand_ty.bitSize(target) > 64)3838 const operand_bits = operand_ty.bitSize(target);
3817 return try cmpBuiltinCall(f, inst, operator, "cmp");3839 if (operand_ty.isInt() and operand_bits > 64)
3840 return cmpBuiltinCall(f, inst, bin_op, operator, .cmp, if (operand_bits > 128) .bits else .none);
3818 if (operand_ty.isRuntimeFloat())3841 if (operand_ty.isRuntimeFloat())
3819 return try cmpBuiltinCall(f, inst, operator, operation);3842 return cmpBuiltinCall(f, inst, bin_op, operator, .operator, .none);
38203843
3821 const inst_ty = f.air.typeOfIndex(inst);3844 const inst_ty = f.air.typeOfIndex(inst);
3822 const lhs = try f.resolveInst(bin_op.lhs);3845 const lhs = try f.resolveInst(bin_op.lhs);
...@@ -3829,7 +3852,7 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation:...@@ -3829,7 +3852,7 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation:
3829 try writer.writeAll(" = ");3852 try writer.writeAll(" = ");
3830 try f.writeCValue(writer, lhs, .Other);3853 try f.writeCValue(writer, lhs, .Other);
3831 try writer.writeByte(' ');3854 try writer.writeByte(' ');
3832 try writer.writeAll(operator);3855 try writer.writeAll(compareOperatorC(operator));
3833 try writer.writeByte(' ');3856 try writer.writeByte(' ');
3834 try f.writeCValue(writer, rhs, .Other);3857 try f.writeCValue(writer, rhs, .Other);
3835 try writer.writeAll(";\n");3858 try writer.writeAll(";\n");
...@@ -3840,9 +3863,7 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation:...@@ -3840,9 +3863,7 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation:
3840fn airEquality(3863fn airEquality(
3841 f: *Function,3864 f: *Function,
3842 inst: Air.Inst.Index,3865 inst: Air.Inst.Index,
3843 negate_prefix: []const u8,3866 operator: std.math.CompareOperator,
3844 operator: []const u8,
3845 operation: []const u8,
3846) !CValue {3867) !CValue {
3847 const bin_op = f.air.instructions.items(.data)[inst].bin_op;3868 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
38483869
...@@ -3853,10 +3874,11 @@ fn airEquality(...@@ -3853,10 +3874,11 @@ fn airEquality(
38533874
3854 const operand_ty = f.air.typeOf(bin_op.lhs);3875 const operand_ty = f.air.typeOf(bin_op.lhs);
3855 const target = f.object.dg.module.getTarget();3876 const target = f.object.dg.module.getTarget();
3856 if (operand_ty.isInt() and operand_ty.bitSize(target) > 64)3877 const operand_bits = operand_ty.bitSize(target);
3857 return try cmpBuiltinCall(f, inst, operator, "cmp");3878 if (operand_ty.isInt() and operand_bits > 64)
3879 return cmpBuiltinCall(f, inst, bin_op, operator, .cmp, if (operand_bits > 128) .bits else .none);
3858 if (operand_ty.isRuntimeFloat())3880 if (operand_ty.isRuntimeFloat())
3859 return try cmpBuiltinCall(f, inst, operator, operation);3881 return cmpBuiltinCall(f, inst, bin_op, operator, .operator, .none);
38603882
3861 const lhs = try f.resolveInst(bin_op.lhs);3883 const lhs = try f.resolveInst(bin_op.lhs);
3862 const rhs = try f.resolveInst(bin_op.rhs);3884 const rhs = try f.resolveInst(bin_op.rhs);
...@@ -3872,7 +3894,12 @@ fn airEquality(...@@ -3872,7 +3894,12 @@ fn airEquality(
3872 // (A && B) || (C && (A == B))3894 // (A && B) || (C && (A == B))
3873 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload3895 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
38743896
3875 try writer.writeAll(negate_prefix);3897 switch (operator) {
3898 .eq => {},
3899 .neq => try writer.writeByte('!'),
3900 else => unreachable,
3901 }
3902 try writer.writeAll("((");
3876 try f.writeCValue(writer, lhs, .Other);3903 try f.writeCValue(writer, lhs, .Other);
3877 try writer.writeAll(".is_null && ");3904 try writer.writeAll(".is_null && ");
3878 try f.writeCValue(writer, rhs, .Other);3905 try f.writeCValue(writer, rhs, .Other);
...@@ -3891,7 +3918,7 @@ fn airEquality(...@@ -3891,7 +3918,7 @@ fn airEquality(
38913918
3892 try f.writeCValue(writer, lhs, .Other);3919 try f.writeCValue(writer, lhs, .Other);
3893 try writer.writeByte(' ');3920 try writer.writeByte(' ');
3894 try writer.writeAll(operator);3921 try writer.writeAll(compareOperatorC(operator));
3895 try writer.writeByte(' ');3922 try writer.writeByte(' ');
3896 try f.writeCValue(writer, rhs, .Other);3923 try f.writeCValue(writer, rhs, .Other);
3897 try writer.writeAll(";\n");3924 try writer.writeAll(";\n");
...@@ -3972,7 +3999,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -3972,7 +3999,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
3972 const inst_ty = f.air.typeOfIndex(inst);3999 const inst_ty = f.air.typeOfIndex(inst);
3973 const target = f.object.dg.module.getTarget();4000 const target = f.object.dg.module.getTarget();
3974 if (inst_ty.isInt() and inst_ty.bitSize(target) > 64)4001 if (inst_ty.isInt() and inst_ty.bitSize(target) > 64)
3975 return try airBinBuiltinCall(f, inst, operation[1..], .None);4002 return try airBinBuiltinCall(f, inst, operation[1..], .none);
3976 if (inst_ty.isRuntimeFloat())4003 if (inst_ty.isRuntimeFloat())
3977 return try airBinFloatOp(f, inst, operation);4004 return try airBinFloatOp(f, inst, operation);
39784005
...@@ -4418,12 +4445,35 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4418,12 +4445,35 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
44184445
4419 // Ensure padding bits have the expected value.4446 // Ensure padding bits have the expected value.
4420 if (dest_ty.isAbiInt()) {4447 if (dest_ty.isAbiInt()) {
4448 const dest_cty = try f.typeToCType(dest_ty, .complete);
4449 const dest_info = dest_ty.intInfo(target);
4450 var wrap_ty_pl = Type.Payload.Bits{ .base = .{ .tag = switch (dest_info.signedness) {
4451 .unsigned => .int_unsigned,
4452 .signed => .int_signed,
4453 } }, .data = dest_info.bits };
4454
4421 try f.writeCValue(writer, local, .Other);4455 try f.writeCValue(writer, local, .Other);
4456 if (dest_cty.castTag(.array)) |pl| {
4457 try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) {
4458 .Little => pl.data.len - 1,
4459 .Big => 0,
4460 }});
4461 wrap_ty_pl.data -= 1;
4462 wrap_ty_pl.data %= @intCast(u16, f.byteSize(f.indexToCType(pl.data.elem_type)) * 8);
4463 wrap_ty_pl.data += 1;
4464 }
4465 const wrap_ty = Type.initPayload(&wrap_ty_pl.base);
4422 try writer.writeAll(" = zig_wrap_");4466 try writer.writeAll(" = zig_wrap_");
4423 try f.object.dg.renderTypeForBuiltinFnName(writer, dest_ty);4467 try f.object.dg.renderTypeForBuiltinFnName(writer, wrap_ty);
4424 try writer.writeByte('(');4468 try writer.writeByte('(');
4425 try f.writeCValue(writer, local, .Other);4469 try f.writeCValue(writer, local, .Other);
4426 try f.object.dg.renderBuiltinInfo(writer, dest_ty, .Bits);4470 if (dest_cty.castTag(.array)) |pl| {
4471 try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) {
4472 .Little => pl.data.len - 1,
4473 .Big => 0,
4474 }});
4475 }
4476 try f.object.dg.renderBuiltinInfo(writer, wrap_ty, .bits);
4427 try writer.writeAll(");\n");4477 try writer.writeAll(");\n");
4428 }4478 }
44294479
...@@ -5438,7 +5488,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5438,7 +5488,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5438 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);5488 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5439 try writer.writeByte(')');5489 try writer.writeByte(')');
5440 if (cant_cast) try writer.writeByte(')');5490 if (cant_cast) try writer.writeByte(')');
5441 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .Bits);5491 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
5442 try writer.writeAll(");\n");5492 try writer.writeAll(");\n");
5443 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;5493 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
54445494
...@@ -5871,7 +5921,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5871,7 +5921,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
5871 try f.writeCValue(writer, operand, .FunctionArgument);5921 try f.writeCValue(writer, operand, .FunctionArgument);
5872 try writer.writeByte(')');5922 try writer.writeByte(')');
5873 if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) {5923 if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) {
5874 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);5924 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
5875 try writer.writeByte(')');5925 try writer.writeByte(')');
5876 }5926 }
5877 try writer.writeAll(";\n");5927 try writer.writeAll(";\n");
...@@ -5972,29 +6022,46 @@ fn airBinBuiltinCall(...@@ -5972,29 +6022,46 @@ fn airBinBuiltinCall(
5972fn cmpBuiltinCall(6022fn cmpBuiltinCall(
5973 f: *Function,6023 f: *Function,
5974 inst: Air.Inst.Index,6024 inst: Air.Inst.Index,
5975 operator: []const u8,6025 data: anytype,
5976 operation: []const u8,6026 operator: std.math.CompareOperator,
6027 operation: enum { cmp, operator },
6028 info: BuiltinInfo,
5977) !CValue {6029) !CValue {
5978 const inst_ty = f.air.typeOfIndex(inst);6030 const inst_ty = f.air.typeOfIndex(inst);
5979 const bin_op = f.air.instructions.items(.data)[inst].bin_op;6031 const operand_ty = f.air.typeOf(data.lhs);
5980 const operand_ty = f.air.typeOf(bin_op.lhs);
59816032
5982 const lhs = try f.resolveInst(bin_op.lhs);6033 const lhs = try f.resolveInst(data.lhs);
5983 const rhs = try f.resolveInst(bin_op.rhs);6034 const rhs = try f.resolveInst(data.rhs);
5984 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6035 try reap(f, inst, &.{ data.lhs, data.rhs });
6036
6037 const ref_ret = inst_ty.tag() != .bool;
59856038
5986 const writer = f.object.writer();6039 const writer = f.object.writer();
5987 const local = try f.allocLocal(inst, inst_ty);6040 const local = try f.allocLocal(inst, inst_ty);
5988 try f.writeCValue(writer, local, .Other);6041 if (!ref_ret) {
5989 try writer.writeAll(" = zig_");6042 try f.writeCValue(writer, local, .Other);
5990 try writer.writeAll(operation);6043 try writer.writeAll(" = ");
5991 try writer.writeByte('_');6044 }
6045 try writer.print("zig_{s}_", .{switch (operation) {
6046 else => @tagName(operation),
6047 .operator => compareOperatorAbbrev(operator),
6048 }});
5992 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);6049 try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty);
5993 try writer.writeByte('(');6050 try writer.writeByte('(');
6051 if (ref_ret) {
6052 try f.writeCValue(writer, local, .FunctionArgument);
6053 try writer.writeAll(", ");
6054 }
5994 try f.writeCValue(writer, lhs, .FunctionArgument);6055 try f.writeCValue(writer, lhs, .FunctionArgument);
5995 try writer.writeAll(", ");6056 try writer.writeAll(", ");
5996 try f.writeCValue(writer, rhs, .FunctionArgument);6057 try f.writeCValue(writer, rhs, .FunctionArgument);
5997 try writer.print(") {s} {};\n", .{ operator, try f.fmtIntLiteral(Type.initTag(.i32), Value.zero) });6058 try f.object.dg.renderBuiltinInfo(writer, operand_ty, info);
6059 try writer.writeByte(')');
6060 if (!ref_ret) try writer.print(" {s} {}", .{
6061 compareOperatorC(operator),
6062 try f.fmtIntLiteral(Type.initTag(.i32), Value.zero),
6063 });
6064 try writer.writeAll(";\n");
5998 return local;6065 return local;
5999}6066}
60006067
...@@ -6675,7 +6742,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6675,7 +6742,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
66756742
6676 try writer.writeAll(", ");6743 try writer.writeAll(", ");
6677 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);6744 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
6678 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);6745 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
6679 try writer.writeByte(')');6746 try writer.writeByte(')');
6680 if (!empty) try writer.writeByte(')');6747 if (!empty) try writer.writeByte(')');
66816748
...@@ -7094,6 +7161,28 @@ fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 {...@@ -7094,6 +7161,28 @@ fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 {
7094 } else unreachable;7161 } else unreachable;
7095}7162}
70967163
7164fn compareOperatorAbbrev(operator: std.math.CompareOperator) []const u8 {
7165 return switch (operator) {
7166 .lt => "lt",
7167 .lte => "le",
7168 .eq => "eq",
7169 .gte => "ge",
7170 .gt => "gt",
7171 .neq => "ne",
7172 };
7173}
7174
7175fn compareOperatorC(operator: std.math.CompareOperator) []const u8 {
7176 return switch (operator) {
7177 .lt => "<",
7178 .lte => "<=",
7179 .eq => "==",
7180 .gte => ">=",
7181 .gt => ">",
7182 .neq => "!=",
7183 };
7184}
7185
7097fn StringLiteral(comptime WriterType: type) type {7186fn StringLiteral(comptime WriterType: type) type {
7098 // MSVC has a length limit of 16380 per string literal (before concatenation)7187 // MSVC has a length limit of 16380 per string literal (before concatenation)
7099 const max_char_len = 4;7188 const max_char_len = 4;
...@@ -7239,14 +7328,6 @@ fn formatIntLiteral(...@@ -7239,14 +7328,6 @@ fn formatIntLiteral(
7239 .positive = undefined,7328 .positive = undefined,
7240 };7329 };
7241 defer allocator.free(wrap.limbs);7330 defer allocator.free(wrap.limbs);
7242 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or
7243 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))
7244 return writer.print("{s}_{s}", .{
7245 data.cty.getStandardDefineAbbrev() orelse return writer.print("zig_{s}Int_{c}{d}", .{
7246 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,
7247 }),
7248 if (int.positive) "MAX" else "MIN",
7249 });
72507331
7251 const c_limb_info: struct {7332 const c_limb_info: struct {
7252 cty: CType,7333 cty: CType,
...@@ -7277,6 +7358,15 @@ fn formatIntLiteral(...@@ -7277,6 +7358,15 @@ fn formatIntLiteral(
7277 },7358 },
7278 };7359 };
7279 if (c_limb_info.count == 1) {7360 if (c_limb_info.count == 1) {
7361 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or
7362 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))
7363 return writer.print("{s}_{s}", .{
7364 data.cty.getStandardDefineAbbrev() orelse return writer.print("zig_{s}Int_{c}{d}", .{
7365 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,
7366 }),
7367 if (int.positive) "MAX" else "MIN",
7368 });
7369
7280 if (!int.positive) try writer.writeByte('-');7370 if (!int.positive) try writer.writeByte('-');
7281 try data.cty.renderLiteralPrefix(writer, data.kind);7371 try data.cty.renderLiteralPrefix(writer, data.kind);
72827372
...@@ -7310,7 +7400,7 @@ fn formatIntLiteral(...@@ -7310,7 +7400,7 @@ fn formatIntLiteral(
7310 try writer.writeAll(string);7400 try writer.writeAll(string);
7311 } else {7401 } else {
7312 try data.cty.renderLiteralPrefix(writer, data.kind);7402 try data.cty.renderLiteralPrefix(writer, data.kind);
7313 wrap.convertToTwosComplement(int, .unsigned, data.int_info.bits);7403 wrap.convertToTwosComplement(int, data.int_info.signedness, c_bits);
7314 std.mem.set(BigIntLimb, wrap.limbs[wrap.len..], 0);7404 std.mem.set(BigIntLimb, wrap.limbs[wrap.len..], 0);
7315 wrap.len = wrap.limbs.len;7405 wrap.len = wrap.limbs.len;
7316 const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count);7406 const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count);
...@@ -7343,7 +7433,7 @@ fn formatIntLiteral(...@@ -7343,7 +7433,7 @@ fn formatIntLiteral(
7343 c_limb_cty = c_limb_info.cty.toSigned();7433 c_limb_cty = c_limb_info.cty.toSigned();
73447434
7345 c_limb_mut.positive = wrap.positive;7435 c_limb_mut.positive = wrap.positive;
7346 c_limb_mut.convertToTwosComplement(7436 c_limb_mut.truncate(
7347 c_limb_mut.toConst(),7437 c_limb_mut.toConst(),
7348 .signed,7438 .signed,
7349 data.int_info.bits - limb_i * @bitSizeOf(BigIntLimb),7439 data.int_info.bits - limb_i * @bitSizeOf(BigIntLimb),
src/codegen/c/type.zig+124
...@@ -496,6 +496,116 @@ pub const CType = extern union {...@@ -496,6 +496,116 @@ 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
499 pub fn toSigned(self: CType) CType {609 pub fn toSigned(self: CType) CType {
500 return CType.initTag(switch (self.tag()) {610 return CType.initTag(switch (self.tag()) {
501 .char, .@"signed char", .@"unsigned char" => .@"signed char",611 .char, .@"signed char", .@"unsigned char" => .@"signed char",
...@@ -725,6 +835,20 @@ pub const CType = extern union {...@@ -725,6 +835,20 @@ pub const CType = extern union {
725 }835 }
726 }836 }
727837
838 pub fn floatActiveBits(self: CType, target: Target) u16 {
839 return switch (self.tag()) {
840 .float => target.c_type_bit_size(.float),
841 .double => target.c_type_bit_size(.double),
842 .@"long double", .zig_c_longdouble => target.c_type_bit_size(.longdouble),
843 .zig_f16 => 16,
844 .zig_f32 => 32,
845 .zig_f64 => 64,
846 .zig_f80 => 80,
847 .zig_f128 => 128,
848 else => unreachable,
849 };
850 }
851
728 pub fn byteSize(self: CType, store: Store.Set, target: Target) u64 {852 pub fn byteSize(self: CType, store: Store.Set, target: Target) u64 {
729 return switch (self.tag()) {853 return switch (self.tag()) {
730 .void => 0,854 .void => 0,
src/type.zig+1-1
...@@ -4213,7 +4213,7 @@ pub const Type = extern union {...@@ -4213,7 +4213,7 @@ pub const Type = extern union {
4213 };4213 };
4214 }4214 }
42154215
4216 fn shallowElemType(child_ty: Type) Type {4216 pub fn shallowElemType(child_ty: Type) Type {
4217 return switch (child_ty.zigTypeTag()) {4217 return switch (child_ty.zigTypeTag()) {
4218 .Array, .Vector => child_ty.childType(),4218 .Array, .Vector => child_ty.childType(),
4219 else => child_ty,4219 else => child_ty,
test/behavior/bitcast.zig-2
...@@ -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;
test/behavior/math.zig-1
...@@ -1526,7 +1526,6 @@ fn testNanEqNan(comptime F: type) !void {...@@ -1526,7 +1526,6 @@ fn testNanEqNan(comptime F: type) !void {
1526}1526}
15271527
1528test "vector comparison" {1528test "vector comparison" {
1529 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1530 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1529 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1531 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1530 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1532 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1531 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
test/behavior/vector.zig-2
...@@ -48,7 +48,6 @@ test "vector wrap operators" {...@@ -48,7 +48,6 @@ test "vector wrap operators" {
4848
49test "vector bin compares with mem.eql" {49test "vector bin compares with mem.eql" {
50 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO50 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; // TODO51 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
53 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO52 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
54 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO53 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -403,7 +402,6 @@ test "initialize vector which is a struct field" {...@@ -403,7 +402,6 @@ test "initialize vector which is a struct field" {
403402
404test "vector comparison operators" {403test "vector comparison operators" {
405 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO404 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; // TODO405 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
408 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO406 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO407 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO