| author | |
| committer | |
| log | 1780d7a348e0f4abfaa71e70eb4cf410a89c00c0 |
| tree | 416fb7f6f3a01e2a083ac02d0c1dd36ce72967a4 |
| parent | 2943df016e62554ef4677acb5bd15e6c7263f108 |
| parent | ff83296256fffb7aba0515abb715a4537a85e054 |
| signature |
6 files changed, 534 insertions(+), 234 deletions(-)
lib/include/zig.h+312-135| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | #if __STDC_VERSION__ >= 201112L |
| 22 | 22 | #define zig_threadlocal thread_local |
| 23 | #elif __GNUC__ | |
| 23 | #elif defined(__GNUC__) | |
| 24 | 24 | #define zig_threadlocal __thread |
| 25 | 25 | #elif _MSC_VER |
| 26 | 26 | #define zig_threadlocal __declspec(thread) |
| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | #define zig_threadlocal zig_threadlocal_unavailable |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #if zig_has_attribute(naked) | |
| 31 | #if zig_has_attribute(naked) || defined(__GNUC__) | |
| 32 | 32 | #define zig_naked __attribute__((naked)) |
| 33 | 33 | #elif defined(_MSC_VER) |
| 34 | 34 | #define zig_naked __declspec(naked) |
| ... | ... | @@ -128,7 +128,7 @@ |
| 128 | 128 | #define zig_atomic_store(obj, arg, order) atomic_store_explicit (obj, arg, order) |
| 129 | 129 | #define zig_atomic_load(obj, order) atomic_load_explicit (obj, order) |
| 130 | 130 | #define zig_fence(order) atomic_thread_fence(order) |
| 131 | #elif __GNUC__ | |
| 131 | #elif defined(__GNUC__) | |
| 132 | 132 | #define memory_order_relaxed __ATOMIC_RELAXED |
| 133 | 133 | #define memory_order_consume __ATOMIC_CONSUME |
| 134 | 134 | #define memory_order_acquire __ATOMIC_ACQUIRE |
| ... | ... | @@ -176,7 +176,7 @@ |
| 176 | 176 | |
| 177 | 177 | #if __STDC_VERSION__ >= 201112L |
| 178 | 178 | #define zig_noreturn _Noreturn void |
| 179 | #elif zig_has_attribute(noreturn) | |
| 179 | #elif zig_has_attribute(noreturn) || defined(__GNUC__) | |
| 180 | 180 | #define zig_noreturn __attribute__((noreturn)) void |
| 181 | 181 | #elif _MSC_VER |
| 182 | 182 | #define zig_noreturn __declspec(noreturn) void |
| ... | ... | @@ -184,6 +184,9 @@ |
| 184 | 184 | #define zig_noreturn void |
| 185 | 185 | #endif |
| 186 | 186 | |
| 187 | #define zig_concat(lhs, rhs) lhs##rhs | |
| 188 | #define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs) | |
| 189 | ||
| 187 | 190 | #define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T)) |
| 188 | 191 | |
| 189 | 192 | typedef void zig_void; |
| ... | ... | @@ -250,110 +253,17 @@ typedef int64_t zig_i64; |
| 250 | 253 | #define zig_minInt_i64 INT64_MIN |
| 251 | 254 | #define zig_maxInt_i64 INT64_MAX |
| 252 | 255 | |
| 253 | #define zig_builtin_f16(name) __##name##h | |
| 254 | #define zig_builtin_constant_f16(name) zig_suffix_f16(__builtin_##name) | |
| 255 | #if FLT_MANT_DIG == 11 | |
| 256 | typedef float zig_f16; | |
| 257 | #define zig_suffix_f16(x) x##f | |
| 258 | #elif DBL_MANT_DIG == 11 | |
| 259 | typedef double zig_f16; | |
| 260 | #define zig_suffix_f16(x) x | |
| 261 | #elif LDBL_MANT_DIG == 11 | |
| 262 | typedef long double zig_f16; | |
| 263 | #define zig_suffix_f16(x) x##l | |
| 264 | #elif FLT16_MANT_DIG == 11 | |
| 265 | typedef _Float16 zig_f16; | |
| 266 | #define zig_suffix_f16(x) x##f16 | |
| 267 | #elif defined(__SIZEOF_FP16__) | |
| 268 | typedef __fp16 zig_f16; | |
| 269 | #define zig_suffix_f16(x) x##f16 | |
| 270 | #endif | |
| 271 | ||
| 272 | #define zig_builtin_f32(name) name##f | |
| 273 | #define zig_builtin_constant_f32(name) zig_suffix_f32(__builtin_##name) | |
| 274 | #if FLT_MANT_DIG == 24 | |
| 275 | typedef float zig_f32; | |
| 276 | #define zig_suffix_f32(x) x##f | |
| 277 | #elif DBL_MANT_DIG == 24 | |
| 278 | typedef double zig_f32; | |
| 279 | #define zig_suffix_f32(x) x | |
| 280 | #elif LDBL_MANT_DIG == 24 | |
| 281 | typedef long double zig_f32; | |
| 282 | #define zig_suffix_f32(x) x##l | |
| 283 | #elif FLT32_MANT_DIG == 24 | |
| 284 | typedef _Float32 zig_f32; | |
| 285 | #define zig_suffix_f32(x) x##f32 | |
| 286 | #endif | |
| 287 | ||
| 288 | #define zig_builtin_f64(name) name | |
| 289 | #define zig_builtin_constant_f64(name) zig_suffix_f64(__builtin_##name) | |
| 290 | #if FLT_MANT_DIG == 53 | |
| 291 | typedef float zig_f64; | |
| 292 | #define zig_suffix_f64(x) x##f | |
| 293 | #elif DBL_MANT_DIG == 53 | |
| 294 | typedef double zig_f64; | |
| 295 | #define zig_suffix_f64(x) x | |
| 296 | #elif LDBL_MANT_DIG == 53 | |
| 297 | typedef long double zig_f64; | |
| 298 | #define zig_suffix_f64(x) x##l | |
| 299 | #elif FLT64_MANT_DIG == 53 | |
| 300 | typedef _Float64 zig_f64; | |
| 301 | #define zig_suffix_f64(x) x##f64 | |
| 302 | #elif FLT32X_MANT_DIG == 53 | |
| 303 | typedef _Float32x zig_f64; | |
| 304 | #define zig_suffix_f64(x) x##f32x | |
| 305 | #endif | |
| 306 | ||
| 307 | #define zig_builtin_f80(name) __##name##x | |
| 308 | #define zig_builtin_constant_f80(name) zig_suffix_f80(__builtin_##name) | |
| 309 | #if FLT_MANT_DIG == 64 | |
| 310 | typedef float zig_f80; | |
| 311 | #define zig_suffix_f80(x) x##f | |
| 312 | #elif DBL_MANT_DIG == 64 | |
| 313 | typedef double zig_f80; | |
| 314 | #define zig_suffix_f80(x) x | |
| 315 | #elif LDBL_MANT_DIG == 64 | |
| 316 | typedef long double zig_f80; | |
| 317 | #define zig_suffix_f80(x) x##l | |
| 318 | #elif FLT80_MANT_DIG == 64 | |
| 319 | typedef _Float80 zig_f80; | |
| 320 | #define zig_suffix_f80(x) x##f80 | |
| 321 | #elif FLT64X_MANT_DIG == 64 | |
| 322 | typedef _Float64x zig_f80; | |
| 323 | #define zig_suffix_f80(x) x##f64x | |
| 324 | #elif defined(__SIZEOF_FLOAT80__) | |
| 325 | typedef __float80 zig_f80; | |
| 326 | #define zig_suffix_f80(x) x##l | |
| 327 | #endif | |
| 328 | ||
| 329 | #define zig_builtin_f128(name) name##q | |
| 330 | #define zig_builtin_constant_f128(name) zig_suffix_f80(__builtin_##name) | |
| 331 | #if FLT_MANT_DIG == 113 | |
| 332 | typedef float zig_f128; | |
| 333 | #define zig_suffix_f128(x) x##f | |
| 334 | #elif DBL_MANT_DIG == 113 | |
| 335 | typedef double zig_f128; | |
| 336 | #define zig_suffix_f128(x) x | |
| 337 | #elif LDBL_MANT_DIG == 113 | |
| 338 | typedef long double zig_f128; | |
| 339 | #define zig_suffix_f128(x) x##l | |
| 340 | #elif FLT128_MANT_DIG == 113 | |
| 341 | typedef _Float128 zig_f128; | |
| 342 | #define zig_suffix_f128(x) x##f128 | |
| 343 | #elif FLT64X_MANT_DIG == 113 | |
| 344 | typedef _Float64x zig_f128; | |
| 345 | #define zig_suffix_f128(x) x##f64x | |
| 346 | #elif defined(__SIZEOF_FLOAT128__) | |
| 347 | typedef __float128 zig_f128; | |
| 348 | #define zig_suffix_f128(x) x##q | |
| 349 | #undef zig_builtin_constant_f128 | |
| 350 | #define zig_builtin_constant_f128(name) __builtin_##name##f128 | |
| 351 | #endif | |
| 352 | ||
| 353 | typedef long double zig_c_longdouble; | |
| 354 | #define zig_suffix_c_longdouble(x) x##l | |
| 355 | #define zig_builtin_c_longdouble(name) zig_suffix_c_longdouble(name) | |
| 356 | #define zig_builtin_constant_c_longdouble(name) zig_suffix_c_longdouble(__builtin_##name) | |
| 256 | #define zig_compiler_rt_abbrev_u32 si | |
| 257 | #define zig_compiler_rt_abbrev_i32 si | |
| 258 | #define zig_compiler_rt_abbrev_u64 di | |
| 259 | #define zig_compiler_rt_abbrev_i64 di | |
| 260 | #define zig_compiler_rt_abbrev_u128 ti | |
| 261 | #define zig_compiler_rt_abbrev_i128 ti | |
| 262 | #define zig_compiler_rt_abbrev_f16 hf | |
| 263 | #define zig_compiler_rt_abbrev_f32 sf | |
| 264 | #define zig_compiler_rt_abbrev_f64 df | |
| 265 | #define zig_compiler_rt_abbrev_f80 xf | |
| 266 | #define zig_compiler_rt_abbrev_f128 tf | |
| 357 | 267 | |
| 358 | 268 | zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize); |
| 359 | 269 | zig_extern_c void *memset (void *, int, zig_usize); |
| ... | ... | @@ -361,7 +271,9 @@ zig_extern_c void *memset (void *, int, zig_usize); |
| 361 | 271 | /* ==================== 8/16/32/64-bit Integer Routines ===================== */ |
| 362 | 272 | |
| 363 | 273 | #define zig_maxInt(Type, bits) zig_shr_##Type(zig_maxInt_##Type, (zig_bitSizeOf(zig_##Type) - bits)) |
| 274 | #define zig_expand_maxInt(Type, bits) zig_maxInt(Type, bits) | |
| 364 | 275 | #define zig_minInt(Type, bits) zig_not_##Type(zig_maxInt(Type, bits), bits) |
| 276 | #define zig_expand_minInt(Type, bits) zig_minInt(Type, bits) | |
| 365 | 277 | |
| 366 | 278 | #define zig_int_operator(Type, RhsType, operation, operator) \ |
| 367 | 279 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \ |
| ... | ... | @@ -954,8 +866,8 @@ static inline zig_u16 zig_bit_reverse_u16(zig_u16 val, zig_u8 bits) { |
| 954 | 866 | #if zig_has_builtin(bitreverse16) |
| 955 | 867 | full_res = __builtin_bitreverse16(val); |
| 956 | 868 | #else |
| 957 | full_res = (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 0)) << 8 | | |
| 958 | (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 8)) >> 0; | |
| 869 | full_res = (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 0), 8) << 8 | | |
| 870 | (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 8), 8) >> 0; | |
| 959 | 871 | #endif |
| 960 | 872 | return zig_wrap_u16(full_res >> (16 - bits), bits); |
| 961 | 873 | } |
| ... | ... | @@ -969,8 +881,8 @@ static inline zig_u32 zig_bit_reverse_u32(zig_u32 val, zig_u8 bits) { |
| 969 | 881 | #if zig_has_builtin(bitreverse32) |
| 970 | 882 | full_res = __builtin_bitreverse32(val); |
| 971 | 883 | #else |
| 972 | full_res = (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 0)) << 16 | | |
| 973 | (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 16)) >> 0; | |
| 884 | full_res = (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 0), 16) << 16 | | |
| 885 | (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 16), 16) >> 0; | |
| 974 | 886 | #endif |
| 975 | 887 | return zig_wrap_u32(full_res >> (32 - bits), bits); |
| 976 | 888 | } |
| ... | ... | @@ -984,8 +896,8 @@ static inline zig_u64 zig_bit_reverse_u64(zig_u64 val, zig_u8 bits) { |
| 984 | 896 | #if zig_has_builtin(bitreverse64) |
| 985 | 897 | full_res = __builtin_bitreverse64(val); |
| 986 | 898 | #else |
| 987 | full_res = (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 0)) << 32 | | |
| 988 | (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 32)) >> 0; | |
| 899 | full_res = (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 0), 32) << 32 | | |
| 900 | (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 32), 32) >> 0; | |
| 989 | 901 | #endif |
| 990 | 902 | return zig_wrap_u64(full_res >> (64 - bits), bits); |
| 991 | 903 | } |
| ... | ... | @@ -1019,7 +931,7 @@ typedef signed __int128 zig_i128; |
| 1019 | 931 | #define zig_bitcast_i128(val) ((zig_i128)(val)) |
| 1020 | 932 | #define zig_cmp_int128(Type) \ |
| 1021 | 933 | static inline zig_i8 zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1022 | return (lhs > rhs) - (lhs < rhs); \ | |
| 934 | return (zig_i8)((lhs > rhs) - (lhs < rhs)); \ | |
| 1023 | 935 | } |
| 1024 | 936 | #define zig_bit_int128(Type, operation, operator) \ |
| 1025 | 937 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| ... | ... | @@ -1211,6 +1123,22 @@ static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1211 | 1123 | #define zig_div_floor_u128 zig_div_trunc_u128 |
| 1212 | 1124 | #define zig_mod_u128 zig_rem_u128 |
| 1213 | 1125 | |
| 1126 | static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) { | |
| 1127 | return zig_cmp_u128(lhs, rhs) < 0 ? lhs : rhs; | |
| 1128 | } | |
| 1129 | ||
| 1130 | static inline zig_i128 zig_min_i128(zig_i128 lhs, zig_i128 rhs) { | |
| 1131 | return zig_cmp_i128(lhs, rhs) < 0 ? lhs : rhs; | |
| 1132 | } | |
| 1133 | ||
| 1134 | static inline zig_u128 zig_max_u128(zig_u128 lhs, zig_u128 rhs) { | |
| 1135 | return zig_cmp_u128(lhs, rhs) > 0 ? lhs : rhs; | |
| 1136 | } | |
| 1137 | ||
| 1138 | static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) { | |
| 1139 | return zig_cmp_i128(lhs, rhs) > 0 ? lhs : rhs; | |
| 1140 | } | |
| 1141 | ||
| 1214 | 1142 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, zig_u8 rhs) { |
| 1215 | 1143 | zig_i128 sign_mask = zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i8(0) ? -zig_as_i128(0, 1) : zig_as_i128(0, 0); |
| 1216 | 1144 | return zig_xor_i128(zig_bitcast_i128(zig_shr_u128(zig_bitcast_u128(zig_xor_i128(lhs, sign_mask)), rhs)), sign_mask); |
| ... | ... | @@ -1460,36 +1388,285 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) { |
| 1460 | 1388 | return zig_bit_reverse_u128(zig_bitcast_u128(val), bits); |
| 1461 | 1389 | } |
| 1462 | 1390 | |
| 1463 | /* ========================== Float Point Routines ========================== */ | |
| 1391 | /* ========================= Floating Point Support ========================= */ | |
| 1392 | ||
| 1393 | #define zig_has_f16 1 | |
| 1394 | #define zig_bitSizeOf_f16 16 | |
| 1395 | #define zig_libc_name_f16(name) __##name##h | |
| 1396 | #define zig_as_special_f16(sign, name, arg, repr) sign zig_as_f16(__builtin_##name, )(arg) | |
| 1397 | #if FLT_MANT_DIG == 11 | |
| 1398 | typedef float zig_f16; | |
| 1399 | #define zig_as_f16(fp, repr) fp##f | |
| 1400 | #elif DBL_MANT_DIG == 11 | |
| 1401 | typedef double zig_f16; | |
| 1402 | #define zig_as_f16(fp, repr) fp | |
| 1403 | #elif LDBL_MANT_DIG == 11 | |
| 1404 | #define zig_bitSizeOf_c_longdouble 16 | |
| 1405 | typedef long double zig_f16; | |
| 1406 | #define zig_as_f16(fp, repr) fp##l | |
| 1407 | #elif FLT16_MANT_DIG == 11 | |
| 1408 | typedef _Float16 zig_f16; | |
| 1409 | #define zig_as_f16(fp, repr) fp##f16 | |
| 1410 | #elif defined(__SIZEOF_FP16__) | |
| 1411 | typedef __fp16 zig_f16; | |
| 1412 | #define zig_as_f16(fp, repr) fp##f16 | |
| 1413 | #else | |
| 1414 | #undef zig_has_f16 | |
| 1415 | #define zig_has_f16 0 | |
| 1416 | #define zig_repr_f16 i16 | |
| 1417 | typedef zig_i16 zig_f16; | |
| 1418 | #define zig_as_f16(fp, repr) repr | |
| 1419 | #undef zig_as_special_f16 | |
| 1420 | #define zig_as_special_f16(sign, name, arg, repr) repr | |
| 1421 | #endif | |
| 1422 | ||
| 1423 | #define zig_has_f32 1 | |
| 1424 | #define zig_bitSizeOf_f32 32 | |
| 1425 | #define zig_libc_name_f32(name) name##f | |
| 1426 | #define zig_as_special_f32(sign, name, arg, repr) sign zig_as_f32(__builtin_##name, )(arg) | |
| 1427 | #if FLT_MANT_DIG == 24 | |
| 1428 | typedef float zig_f32; | |
| 1429 | #define zig_as_f32(fp, repr) fp##f | |
| 1430 | #elif DBL_MANT_DIG == 24 | |
| 1431 | typedef double zig_f32; | |
| 1432 | #define zig_as_f32(fp, repr) fp | |
| 1433 | #elif LDBL_MANT_DIG == 24 | |
| 1434 | #define zig_bitSizeOf_c_longdouble 32 | |
| 1435 | typedef long double zig_f32; | |
| 1436 | #define zig_as_f32(fp, repr) fp##l | |
| 1437 | #elif FLT32_MANT_DIG == 24 | |
| 1438 | typedef _Float32 zig_f32; | |
| 1439 | #define zig_as_f32(fp, repr) fp##f32 | |
| 1440 | #else | |
| 1441 | #undef zig_has_f32 | |
| 1442 | #define zig_has_f32 0 | |
| 1443 | #define zig_repr_f32 i32 | |
| 1444 | typedef zig_i32 zig_f32; | |
| 1445 | #define zig_as_f32(fp, repr) repr | |
| 1446 | #undef zig_as_special_f32 | |
| 1447 | #define zig_as_special_f32(sign, name, arg, repr) repr | |
| 1448 | #endif | |
| 1449 | ||
| 1450 | #define zig_has_f64 1 | |
| 1451 | #define zig_bitSizeOf_f64 64 | |
| 1452 | #define zig_libc_name_f64(name) name | |
| 1453 | #define zig_as_special_f64(sign, name, arg, repr) sign zig_as_f64(__builtin_##name, )(arg) | |
| 1454 | #if FLT_MANT_DIG == 53 | |
| 1455 | typedef float zig_f64; | |
| 1456 | #define zig_as_f64(fp, repr) fp##f | |
| 1457 | #elif DBL_MANT_DIG == 53 | |
| 1458 | typedef double zig_f64; | |
| 1459 | #define zig_as_f64(fp, repr) fp | |
| 1460 | #elif LDBL_MANT_DIG == 53 | |
| 1461 | #define zig_bitSizeOf_c_longdouble 64 | |
| 1462 | typedef long double zig_f64; | |
| 1463 | #define zig_as_f64(fp, repr) fp##l | |
| 1464 | #elif FLT64_MANT_DIG == 53 | |
| 1465 | typedef _Float64 zig_f64; | |
| 1466 | #define zig_as_f64(fp, repr) fp##f64 | |
| 1467 | #elif FLT32X_MANT_DIG == 53 | |
| 1468 | typedef _Float32x zig_f64; | |
| 1469 | #define zig_as_f64(fp, repr) fp##f32x | |
| 1470 | #else | |
| 1471 | #undef zig_has_f64 | |
| 1472 | #define zig_has_f64 0 | |
| 1473 | #define zig_repr_f64 i64 | |
| 1474 | typedef zig_i64 zig_f64; | |
| 1475 | #define zig_as_f64(fp, repr) repr | |
| 1476 | #undef zig_as_special_f64 | |
| 1477 | #define zig_as_special_f64(sign, name, arg, repr) repr | |
| 1478 | #endif | |
| 1479 | ||
| 1480 | #define zig_has_f80 1 | |
| 1481 | #define zig_bitSizeOf_f80 80 | |
| 1482 | #define zig_libc_name_f80(name) __##name##x | |
| 1483 | #define zig_as_special_f80(sign, name, arg, repr) sign zig_as_f80(__builtin_##name, )(arg) | |
| 1484 | #if FLT_MANT_DIG == 64 | |
| 1485 | typedef float zig_f80; | |
| 1486 | #define zig_as_f80(fp, repr) fp##f | |
| 1487 | #elif DBL_MANT_DIG == 64 | |
| 1488 | typedef double zig_f80; | |
| 1489 | #define zig_as_f80(fp, repr) fp | |
| 1490 | #elif LDBL_MANT_DIG == 64 | |
| 1491 | #define zig_bitSizeOf_c_longdouble 80 | |
| 1492 | typedef long double zig_f80; | |
| 1493 | #define zig_as_f80(fp, repr) fp##l | |
| 1494 | #elif FLT80_MANT_DIG == 64 | |
| 1495 | typedef _Float80 zig_f80; | |
| 1496 | #define zig_as_f80(fp, repr) fp##f80 | |
| 1497 | #elif FLT64X_MANT_DIG == 64 | |
| 1498 | typedef _Float64x zig_f80; | |
| 1499 | #define zig_as_f80(fp, repr) fp##f64x | |
| 1500 | #elif defined(__SIZEOF_FLOAT80__) | |
| 1501 | typedef __float80 zig_f80; | |
| 1502 | #define zig_as_f80(fp, repr) fp##l | |
| 1503 | #else | |
| 1504 | #undef zig_has_f80 | |
| 1505 | #define zig_has_f80 0 | |
| 1506 | #define zig_repr_f80 i128 | |
| 1507 | typedef zig_i128 zig_f80; | |
| 1508 | #define zig_as_f80(fp, repr) repr | |
| 1509 | #undef zig_as_special_f80 | |
| 1510 | #define zig_as_special_f80(sign, name, arg, repr) repr | |
| 1511 | #endif | |
| 1512 | ||
| 1513 | #define zig_has_f128 1 | |
| 1514 | #define zig_bitSizeOf_f128 128 | |
| 1515 | #define zig_libc_name_f128(name) name##q | |
| 1516 | #define zig_as_special_f128(sign, name, arg, repr) sign zig_as_f128(__builtin_##name, )(arg) | |
| 1517 | #if FLT_MANT_DIG == 113 | |
| 1518 | typedef float zig_f128; | |
| 1519 | #define zig_as_f128(fp, repr) fp##f | |
| 1520 | #elif DBL_MANT_DIG == 113 | |
| 1521 | typedef double zig_f128; | |
| 1522 | #define zig_as_f128(fp, repr) fp | |
| 1523 | #elif LDBL_MANT_DIG == 113 | |
| 1524 | #define zig_bitSizeOf_c_longdouble 128 | |
| 1525 | typedef long double zig_f128; | |
| 1526 | #define zig_as_f128(fp, repr) fp##l | |
| 1527 | #elif FLT128_MANT_DIG == 113 | |
| 1528 | typedef _Float128 zig_f128; | |
| 1529 | #define zig_as_f128(fp, repr) fp##f128 | |
| 1530 | #elif FLT64X_MANT_DIG == 113 | |
| 1531 | typedef _Float64x zig_f128; | |
| 1532 | #define zig_as_f128(fp, repr) fp##f64x | |
| 1533 | #elif defined(__SIZEOF_FLOAT128__) | |
| 1534 | typedef __float128 zig_f128; | |
| 1535 | #define zig_as_f128(fp, repr) fp##q | |
| 1536 | #undef zig_as_special_f128 | |
| 1537 | #define zig_as_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg) | |
| 1538 | #else | |
| 1539 | #undef zig_has_f128 | |
| 1540 | #define zig_has_f128 0 | |
| 1541 | #define zig_repr_f128 i128 | |
| 1542 | typedef zig_i128 zig_f128; | |
| 1543 | #define zig_as_f128(fp, repr) repr | |
| 1544 | #undef zig_as_special_f128 | |
| 1545 | #define zig_as_special_f128(sign, name, arg, repr) repr | |
| 1546 | #endif | |
| 1547 | ||
| 1548 | #define zig_has_c_longdouble 1 | |
| 1549 | typedef long double zig_c_longdouble; | |
| 1550 | #define zig_as_c_longdouble(fp, repr) fp##l | |
| 1551 | #define zig_libc_name_c_longdouble(name) name##l | |
| 1552 | #define zig_as_special_c_longdouble(sign, name, arg, repr) sign __builtin_##name##l(arg) | |
| 1553 | ||
| 1554 | #define zig_convert_builtin(ResType, operation, ArgType, version) \ | |
| 1555 | zig_extern_c zig_##ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ | |
| 1556 | zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(zig_##ArgType); | |
| 1557 | zig_convert_builtin(f16, trunc, f32, 2) | |
| 1558 | zig_convert_builtin(f16, trunc, f64, 2) | |
| 1559 | zig_convert_builtin(f16, trunc, f80, 2) | |
| 1560 | zig_convert_builtin(f16, trunc, f128, 2) | |
| 1561 | zig_convert_builtin(f32, extend, f16, 2) | |
| 1562 | zig_convert_builtin(f32, trunc, f64, 2) | |
| 1563 | zig_convert_builtin(f32, trunc, f80, 2) | |
| 1564 | zig_convert_builtin(f32, trunc, f128, 2) | |
| 1565 | zig_convert_builtin(f64, extend, f16, 2) | |
| 1566 | zig_convert_builtin(f64, extend, f32, 2) | |
| 1567 | zig_convert_builtin(f64, trunc, f80, 2) | |
| 1568 | zig_convert_builtin(f64, trunc, f128, 2) | |
| 1569 | zig_convert_builtin(f80, extend, f16, 2) | |
| 1570 | zig_convert_builtin(f80, extend, f32, 2) | |
| 1571 | zig_convert_builtin(f80, extend, f64, 2) | |
| 1572 | zig_convert_builtin(f80, trunc, f128, 2) | |
| 1573 | zig_convert_builtin(f128, extend, f16, 2) | |
| 1574 | zig_convert_builtin(f128, extend, f32, 2) | |
| 1575 | zig_convert_builtin(f128, extend, f64, 2) | |
| 1576 | zig_convert_builtin(f128, extend, f80, 2) | |
| 1577 | ||
| 1578 | #define zig_float_negate_builtin_0(Type) \ | |
| 1579 | static inline zig_##Type zig_neg_##Type(zig_##Type arg) { \ | |
| 1580 | return zig_expand_concat(zig_xor_, zig_repr_##Type)(arg, zig_expand_minInt(zig_repr_##Type, zig_bitSizeOf_##Type)); \ | |
| 1581 | } | |
| 1582 | #define zig_float_negate_builtin_1(Type) \ | |
| 1583 | static inline zig_##Type zig_neg_##Type(zig_##Type arg) { \ | |
| 1584 | return -arg; \ | |
| 1585 | } | |
| 1586 | ||
| 1587 | #define zig_float_less_builtin_0(Type, operation) \ | |
| 1588 | zig_extern_c zig_i8 zig_expand_concat(zig_expand_concat(__##operation, \ | |
| 1589 | zig_compiler_rt_abbrev_##Type), 2)(zig_##Type, zig_##Type); \ | |
| 1590 | static inline zig_i8 zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | |
| 1591 | return (zig_i8)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 2)(lhs, rhs); \ | |
| 1592 | } | |
| 1593 | #define zig_float_less_builtin_1(Type, operation) \ | |
| 1594 | static inline zig_i8 zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | |
| 1595 | return (zig_i8)(!(lhs <= rhs) - (lhs < rhs)); \ | |
| 1596 | } | |
| 1597 | ||
| 1598 | #define zig_float_greater_builtin_0(Type, operation) \ | |
| 1599 | zig_float_less_builtin_0(Type, operation) | |
| 1600 | #define zig_float_greater_builtin_1(Type, operation) \ | |
| 1601 | static inline zig_i8 zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | |
| 1602 | return (zig_i8)((lhs > rhs) - !(lhs >= rhs)); \ | |
| 1603 | } | |
| 1604 | ||
| 1605 | #define zig_float_binary_builtin_0(Type, operation, operator) \ | |
| 1606 | zig_extern_c zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \ | |
| 1607 | zig_compiler_rt_abbrev_##Type), 3)(zig_##Type, zig_##Type); \ | |
| 1608 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | |
| 1609 | return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 3)(lhs, rhs); \ | |
| 1610 | } | |
| 1611 | #define zig_float_binary_builtin_1(Type, operation, operator) \ | |
| 1612 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | |
| 1613 | return lhs operator rhs; \ | |
| 1614 | } | |
| 1464 | 1615 | |
| 1465 | 1616 | #define zig_float_builtins(Type) \ |
| 1466 | zig_extern_c zig_##Type zig_builtin_##Type(sqrt)(zig_##Type); \ | |
| 1467 | zig_extern_c zig_##Type zig_builtin_##Type(sin)(zig_##Type); \ | |
| 1468 | zig_extern_c zig_##Type zig_builtin_##Type(cos)(zig_##Type); \ | |
| 1469 | zig_extern_c zig_##Type zig_builtin_##Type(tan)(zig_##Type); \ | |
| 1470 | zig_extern_c zig_##Type zig_builtin_##Type(exp)(zig_##Type); \ | |
| 1471 | zig_extern_c zig_##Type zig_builtin_##Type(exp2)(zig_##Type); \ | |
| 1472 | zig_extern_c zig_##Type zig_builtin_##Type(log)(zig_##Type); \ | |
| 1473 | zig_extern_c zig_##Type zig_builtin_##Type(log2)(zig_##Type); \ | |
| 1474 | zig_extern_c zig_##Type zig_builtin_##Type(log10)(zig_##Type); \ | |
| 1475 | zig_extern_c zig_##Type zig_builtin_##Type(fabs)(zig_##Type); \ | |
| 1476 | zig_extern_c zig_##Type zig_builtin_##Type(floor)(zig_##Type); \ | |
| 1477 | zig_extern_c zig_##Type zig_builtin_##Type(ceil)(zig_##Type); \ | |
| 1478 | zig_extern_c zig_##Type zig_builtin_##Type(round)(zig_##Type); \ | |
| 1479 | zig_extern_c zig_##Type zig_builtin_##Type(trunc)(zig_##Type); \ | |
| 1480 | zig_extern_c zig_##Type zig_builtin_##Type(fmod)(zig_##Type, zig_##Type); \ | |
| 1481 | zig_extern_c zig_##Type zig_builtin_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \ | |
| 1617 | zig_convert_builtin(i32, fix, Type, ) \ | |
| 1618 | zig_convert_builtin(u32, fixuns, Type, ) \ | |
| 1619 | zig_convert_builtin(i64, fix, Type, ) \ | |
| 1620 | zig_convert_builtin(u64, fixuns, Type, ) \ | |
| 1621 | zig_convert_builtin(i128, fix, Type, ) \ | |
| 1622 | zig_convert_builtin(u128, fixuns, Type, ) \ | |
| 1623 | zig_convert_builtin(Type, float, i32, ) \ | |
| 1624 | zig_convert_builtin(Type, floatun, u32, ) \ | |
| 1625 | zig_convert_builtin(Type, float, i64, ) \ | |
| 1626 | zig_convert_builtin(Type, floatun, u64, ) \ | |
| 1627 | zig_convert_builtin(Type, float, i128, ) \ | |
| 1628 | zig_convert_builtin(Type, floatun, u128, ) \ | |
| 1629 | zig_expand_concat(zig_float_negate_builtin_, zig_has_##Type)(Type) \ | |
| 1630 | zig_expand_concat(zig_float_less_builtin_, zig_has_##Type)(Type, cmp) \ | |
| 1631 | zig_expand_concat(zig_float_less_builtin_, zig_has_##Type)(Type, ne) \ | |
| 1632 | zig_expand_concat(zig_float_less_builtin_, zig_has_##Type)(Type, eq) \ | |
| 1633 | zig_expand_concat(zig_float_less_builtin_, zig_has_##Type)(Type, lt) \ | |
| 1634 | zig_expand_concat(zig_float_less_builtin_, zig_has_##Type)(Type, le) \ | |
| 1635 | zig_expand_concat(zig_float_greater_builtin_, zig_has_##Type)(Type, gt) \ | |
| 1636 | zig_expand_concat(zig_float_greater_builtin_, zig_has_##Type)(Type, ge) \ | |
| 1637 | zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, add, +) \ | |
| 1638 | zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, sub, -) \ | |
| 1639 | zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, mul, *) \ | |
| 1640 | zig_expand_concat(zig_float_binary_builtin_, zig_has_##Type)(Type, div, /) \ | |
| 1641 | zig_extern_c zig_##Type zig_libc_name_##Type(sqrt)(zig_##Type); \ | |
| 1642 | zig_extern_c zig_##Type zig_libc_name_##Type(sin)(zig_##Type); \ | |
| 1643 | zig_extern_c zig_##Type zig_libc_name_##Type(cos)(zig_##Type); \ | |
| 1644 | zig_extern_c zig_##Type zig_libc_name_##Type(tan)(zig_##Type); \ | |
| 1645 | zig_extern_c zig_##Type zig_libc_name_##Type(exp)(zig_##Type); \ | |
| 1646 | zig_extern_c zig_##Type zig_libc_name_##Type(exp2)(zig_##Type); \ | |
| 1647 | zig_extern_c zig_##Type zig_libc_name_##Type(log)(zig_##Type); \ | |
| 1648 | zig_extern_c zig_##Type zig_libc_name_##Type(log2)(zig_##Type); \ | |
| 1649 | zig_extern_c zig_##Type zig_libc_name_##Type(log10)(zig_##Type); \ | |
| 1650 | zig_extern_c zig_##Type zig_libc_name_##Type(fabs)(zig_##Type); \ | |
| 1651 | zig_extern_c zig_##Type zig_libc_name_##Type(floor)(zig_##Type); \ | |
| 1652 | zig_extern_c zig_##Type zig_libc_name_##Type(ceil)(zig_##Type); \ | |
| 1653 | zig_extern_c zig_##Type zig_libc_name_##Type(round)(zig_##Type); \ | |
| 1654 | zig_extern_c zig_##Type zig_libc_name_##Type(trunc)(zig_##Type); \ | |
| 1655 | zig_extern_c zig_##Type zig_libc_name_##Type(fmod)(zig_##Type, zig_##Type); \ | |
| 1656 | zig_extern_c zig_##Type zig_libc_name_##Type(fmin)(zig_##Type, zig_##Type); \ | |
| 1657 | zig_extern_c zig_##Type zig_libc_name_##Type(fmax)(zig_##Type, zig_##Type); \ | |
| 1658 | zig_extern_c zig_##Type zig_libc_name_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \ | |
| 1482 | 1659 | \ |
| 1483 | 1660 | static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1484 | return zig_builtin_##Type(trunc)(lhs / rhs); \ | |
| 1661 | return zig_libc_name_##Type(trunc)(zig_div_##Type(lhs, rhs)); \ | |
| 1485 | 1662 | } \ |
| 1486 | 1663 | \ |
| 1487 | 1664 | static inline zig_##Type zig_div_floor_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1488 | return zig_builtin_##Type(floor)(lhs / rhs); \ | |
| 1665 | return zig_libc_name_##Type(floor)(zig_div_##Type(lhs, rhs)); \ | |
| 1489 | 1666 | } \ |
| 1490 | 1667 | \ |
| 1491 | 1668 | static inline zig_##Type zig_mod_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 1492 | return lhs - zig_div_floor_##Type(lhs, rhs) * rhs; \ | |
| 1669 | return zig_sub_##Type(lhs, zig_mul_##Type(zig_div_floor_##Type(lhs, rhs), rhs)); \ | |
| 1493 | 1670 | } |
| 1494 | 1671 | zig_float_builtins(f16) |
| 1495 | 1672 | zig_float_builtins(f32) |
lib/std/start.zig+9-1| ... | ... | @@ -281,7 +281,15 @@ fn _start() callconv(.Naked) noreturn { |
| 281 | 281 | \\ andl $-16, %%esp |
| 282 | 282 | \\ jmp _posixCallMainAndExit |
| 283 | 283 | ), |
| 284 | .aarch64, .aarch64_be, .arm, .armeb, .thumb => asm volatile ( | |
| 284 | .aarch64, .aarch64_be => asm volatile ( | |
| 285 | \\ mov fp, #0 | |
| 286 | \\ mov lr, #0 | |
| 287 | \\ mov x0, sp | |
| 288 | \\ adrp x1, argc_argv_ptr | |
| 289 | \\ str x0, [x1, :lo12:argc_argv_ptr] | |
| 290 | \\ b _posixCallMainAndExit | |
| 291 | ), | |
| 292 | .arm, .armeb, .thumb => asm volatile ( | |
| 285 | 293 | \\ mov fp, #0 |
| 286 | 294 | \\ mov lr, #0 |
| 287 | 295 | \\ str sp, argc_argv_ptr |
lib/test_runner.zig+2-1| ... | ... | @@ -130,7 +130,8 @@ pub fn main2() anyerror!void { |
| 130 | 130 | } |
| 131 | 131 | if (builtin.zig_backend == .stage2_wasm or |
| 132 | 132 | builtin.zig_backend == .stage2_x86_64 or |
| 133 | builtin.zig_backend == .stage2_llvm) | |
| 133 | builtin.zig_backend == .stage2_llvm or | |
| 134 | builtin.zig_backend == .stage2_c) | |
| 134 | 135 | { |
| 135 | 136 | const passed = builtin.test_functions.len - skipped - failed; |
| 136 | 137 | const stderr = std.io.getStdErr(); |
src/codegen/c.zig+201-91| ... | ... | @@ -19,6 +19,7 @@ const Liveness = @import("../Liveness.zig"); |
| 19 | 19 | const CType = @import("../type.zig").CType; |
| 20 | 20 | |
| 21 | 21 | const Mutability = enum { Const, ConstArgument, Mut }; |
| 22 | const BigIntLimb = std.math.big.Limb; | |
| 22 | 23 | const BigInt = std.math.big.int; |
| 23 | 24 | |
| 24 | 25 | pub const CValue = union(enum) { |
| ... | ... | @@ -608,19 +609,25 @@ pub const DeclGen = struct { |
| 608 | 609 | .Bool => return dg.renderValue(writer, ty, Value.@"false", location), |
| 609 | 610 | .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val)}), |
| 610 | 611 | .Float => { |
| 612 | const bits = ty.floatBits(target); | |
| 613 | var int_pl = Type.Payload.Bits{ .base = .{ .tag = .int_signed }, .data = bits }; | |
| 614 | const int_ty = Type.initPayload(&int_pl.base); | |
| 615 | ||
| 611 | 616 | try writer.writeByte('('); |
| 612 | 617 | try dg.renderTypecast(writer, ty); |
| 613 | try writer.writeAll(")zig_suffix_"); | |
| 618 | try writer.writeAll(")zig_as_"); | |
| 614 | 619 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 615 | 620 | try writer.writeByte('('); |
| 616 | switch (ty.floatBits(target)) { | |
| 617 | 16 => try writer.print("{x}", .{@bitCast(f16, undefPattern(u16))}), | |
| 618 | 32 => try writer.print("{x}", .{@bitCast(f32, undefPattern(u32))}), | |
| 619 | 64 => try writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}), | |
| 620 | 80 => try writer.print("{x}", .{@bitCast(f80, undefPattern(u80))}), | |
| 621 | 128 => try writer.print("{x}", .{@bitCast(f128, undefPattern(u128))}), | |
| 621 | switch (bits) { | |
| 622 | 16 => try writer.print("{x}", .{@bitCast(f16, undefPattern(i16))}), | |
| 623 | 32 => try writer.print("{x}", .{@bitCast(f32, undefPattern(i32))}), | |
| 624 | 64 => try writer.print("{x}", .{@bitCast(f64, undefPattern(i64))}), | |
| 625 | 80 => try writer.print("{x}", .{@bitCast(f80, undefPattern(i80))}), | |
| 626 | 128 => try writer.print("{x}", .{@bitCast(f128, undefPattern(i128))}), | |
| 622 | 627 | else => unreachable, |
| 623 | 628 | } |
| 629 | try writer.writeAll(", "); | |
| 630 | try dg.renderValue(writer, int_ty, Value.undef, .FunctionArgument); | |
| 624 | 631 | return writer.writeByte(')'); |
| 625 | 632 | }, |
| 626 | 633 | .Pointer => if (ty.isSlice()) { |
| ... | ... | @@ -770,21 +777,48 @@ pub const DeclGen = struct { |
| 770 | 777 | else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val)}), |
| 771 | 778 | }, |
| 772 | 779 | .Float => { |
| 780 | const bits = ty.floatBits(target); | |
| 781 | const f128_val = val.toFloat(f128); | |
| 782 | ||
| 783 | var int_ty_pl = Type.Payload.Bits{ .base = .{ .tag = .int_signed }, .data = bits }; | |
| 784 | const int_ty = Type.initPayload(&int_ty_pl.base); | |
| 785 | ||
| 786 | assert(bits <= 128); | |
| 787 | var int_val_limbs: [BigInt.calcTwosCompLimbCount(128)]BigIntLimb = undefined; | |
| 788 | var int_val_big = BigInt.Mutable{ | |
| 789 | .limbs = &int_val_limbs, | |
| 790 | .len = undefined, | |
| 791 | .positive = undefined, | |
| 792 | }; | |
| 793 | ||
| 794 | switch (bits) { | |
| 795 | 16 => int_val_big.set(@bitCast(i16, val.toFloat(f16))), | |
| 796 | 32 => int_val_big.set(@bitCast(i32, val.toFloat(f32))), | |
| 797 | 64 => int_val_big.set(@bitCast(i64, val.toFloat(f64))), | |
| 798 | 80 => int_val_big.set(@bitCast(i80, val.toFloat(f80))), | |
| 799 | 128 => int_val_big.set(@bitCast(i128, f128_val)), | |
| 800 | else => unreachable, | |
| 801 | } | |
| 802 | ||
| 803 | var int_val_pl = Value.Payload.BigInt{ | |
| 804 | .base = .{ .tag = if (int_val_big.positive) .int_big_positive else .int_big_negative }, | |
| 805 | .data = int_val_big.limbs[0..int_val_big.len], | |
| 806 | }; | |
| 807 | const int_val = Value.initPayload(&int_val_pl.base); | |
| 808 | ||
| 773 | 809 | try writer.writeByte('('); |
| 774 | 810 | try dg.renderTypecast(writer, ty); |
| 775 | 811 | try writer.writeByte(')'); |
| 776 | const f128_val = val.toFloat(f128); | |
| 777 | if (std.math.signbit(f128_val)) try writer.writeByte('-'); | |
| 778 | 812 | if (std.math.isFinite(f128_val)) { |
| 779 | try writer.writeAll("zig_suffix_"); | |
| 813 | try writer.writeAll("zig_as_"); | |
| 780 | 814 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 781 | 815 | try writer.writeByte('('); |
| 782 | switch (ty.floatBits(target)) { | |
| 783 | 16 => try writer.print("{x}", .{@fabs(val.toFloat(f16))}), | |
| 784 | 32 => try writer.print("{x}", .{@fabs(val.toFloat(f32))}), | |
| 785 | 64 => try writer.print("{x}", .{@fabs(val.toFloat(f64))}), | |
| 786 | 80 => try writer.print("{x}", .{@fabs(val.toFloat(f80))}), | |
| 787 | 128 => try writer.print("{x}", .{@fabs(f128_val)}), | |
| 816 | switch (bits) { | |
| 817 | 16 => try writer.print("{x}", .{val.toFloat(f16)}), | |
| 818 | 32 => try writer.print("{x}", .{val.toFloat(f32)}), | |
| 819 | 64 => try writer.print("{x}", .{val.toFloat(f64)}), | |
| 820 | 80 => try writer.print("{x}", .{val.toFloat(f80)}), | |
| 821 | 128 => try writer.print("{x}", .{f128_val}), | |
| 788 | 822 | else => unreachable, |
| 789 | 823 | } |
| 790 | 824 | } else { |
| ... | ... | @@ -796,23 +830,26 @@ pub const DeclGen = struct { |
| 796 | 830 | "inf" |
| 797 | 831 | else |
| 798 | 832 | unreachable; |
| 799 | try writer.writeAll("zig_builtin_constant_"); | |
| 833 | ||
| 834 | try writer.writeAll("zig_as_special_"); | |
| 800 | 835 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 801 | 836 | try writer.writeByte('('); |
| 837 | if (std.math.signbit(f128_val)) try writer.writeByte('-'); | |
| 838 | try writer.writeAll(", "); | |
| 802 | 839 | try writer.writeAll(operation); |
| 803 | try writer.writeAll(")("); | |
| 804 | if (std.math.isNan(f128_val)) switch (ty.floatBits(target)) { | |
| 840 | try writer.writeAll(", "); | |
| 841 | if (std.math.isNan(f128_val)) switch (bits) { | |
| 805 | 842 | // We only actually need to pass the significand, but it will get |
| 806 | 843 | // properly masked anyway, so just pass the whole value. |
| 807 | 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, @fabs(val.toFloat(f16)))}), | |
| 808 | 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, @fabs(val.toFloat(f32)))}), | |
| 809 | 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, @fabs(val.toFloat(f64)))}), | |
| 810 | 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, @fabs(val.toFloat(f80)))}), | |
| 811 | 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, @fabs(f128_val))}), | |
| 844 | 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, val.toFloat(f16))}), | |
| 845 | 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, val.toFloat(f32))}), | |
| 846 | 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, val.toFloat(f64))}), | |
| 847 | 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, val.toFloat(f80))}), | |
| 848 | 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, f128_val)}), | |
| 812 | 849 | else => unreachable, |
| 813 | 850 | }; |
| 814 | 851 | } |
| 815 | return writer.writeByte(')'); | |
| 852 | return writer.print(", {x})", .{try dg.fmtIntLiteral(int_ty, int_val)}); | |
| 816 | 853 | }, |
| 817 | 854 | .Pointer => switch (val.tag()) { |
| 818 | 855 | .null_value, .zero => if (ty.isSlice()) { |
| ... | ... | @@ -2299,11 +2336,14 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 2299 | 2336 | |
| 2300 | 2337 | // TODO use a different strategy for add, sub, mul, div |
| 2301 | 2338 | // that communicates to the optimizer that wrapping is UB. |
| 2302 | .add => try airBinOp(f, inst, "+", "add", .None), | |
| 2303 | .sub => try airBinOp(f, inst, "-", "sub", .None), | |
| 2304 | .mul => try airBinOp(f, inst, "*", "mul", .None), | |
| 2305 | .div_float, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None), | |
| 2339 | .add => try airBinOp(f, inst, "+", "add", .None), | |
| 2340 | .sub => try airBinOp(f, inst, "-", "sub", .None), | |
| 2341 | .mul => try airBinOp(f, inst, "*", "mul", .None), | |
| 2342 | ||
| 2343 | .neg => try airFloatNeg(f, inst), | |
| 2344 | .div_float => try airBinBuiltinCall(f, inst, "div", .None), | |
| 2306 | 2345 | |
| 2346 | .div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None), | |
| 2307 | 2347 | .rem => blk: { |
| 2308 | 2348 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2309 | 2349 | const lhs_ty = f.air.typeOf(bin_op.lhs); |
| ... | ... | @@ -2314,16 +2354,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 2314 | 2354 | else |
| 2315 | 2355 | try airBinFloatOp(f, inst, "fmod"); |
| 2316 | 2356 | }, |
| 2317 | .div_trunc => blk: { | |
| 2318 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | |
| 2319 | const lhs_ty = f.air.typeOf(bin_op.lhs); | |
| 2320 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), | |
| 2321 | // so we only check one. | |
| 2322 | break :blk if (lhs_ty.isInt()) | |
| 2323 | try airBinOp(f, inst, "/", "div_trunc", .None) | |
| 2324 | else | |
| 2325 | try airBinBuiltinCall(f, inst, "div_trunc", .None); | |
| 2326 | }, | |
| 2327 | 2357 | .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None), |
| 2328 | 2358 | .mod => try airBinBuiltinCall(f, inst, "mod", .None), |
| 2329 | 2359 | |
| ... | ... | @@ -2336,8 +2366,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 2336 | 2366 | .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits), |
| 2337 | 2367 | .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits), |
| 2338 | 2368 | |
| 2339 | .neg => try airNeg(f, inst), | |
| 2340 | ||
| 2341 | 2369 | .sqrt, |
| 2342 | 2370 | .sin, |
| 2343 | 2371 | .cos, |
| ... | ... | @@ -2361,18 +2389,18 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 2361 | 2389 | .mul_with_overflow => try airOverflow(f, inst, "mul", .Bits), |
| 2362 | 2390 | .shl_with_overflow => try airOverflow(f, inst, "shl", .Bits), |
| 2363 | 2391 | |
| 2364 | .min => try airMinMax(f, inst, '<'), | |
| 2365 | .max => try airMinMax(f, inst, '>'), | |
| 2392 | .min => try airMinMax(f, inst, '<', "fmin"), | |
| 2393 | .max => try airMinMax(f, inst, '>', "fmax"), | |
| 2366 | 2394 | |
| 2367 | 2395 | .slice => try airSlice(f, inst), |
| 2368 | 2396 | |
| 2369 | .cmp_gt => try airCmpOp(f, inst, ">"), | |
| 2370 | .cmp_gte => try airCmpOp(f, inst, ">="), | |
| 2371 | .cmp_lt => try airCmpOp(f, inst, "<"), | |
| 2372 | .cmp_lte => try airCmpOp(f, inst, "<="), | |
| 2397 | .cmp_gt => try airCmpOp(f, inst, ">", "gt"), | |
| 2398 | .cmp_gte => try airCmpOp(f, inst, ">=", "ge"), | |
| 2399 | .cmp_lt => try airCmpOp(f, inst, "<", "lt"), | |
| 2400 | .cmp_lte => try airCmpOp(f, inst, "<=", "le"), | |
| 2373 | 2401 | |
| 2374 | .cmp_eq => try airEquality(f, inst, "((", "=="), | |
| 2375 | .cmp_neq => try airEquality(f, inst, "!((", "!="), | |
| 2402 | .cmp_eq => try airEquality(f, inst, "((", "==", "eq"), | |
| 2403 | .cmp_neq => try airEquality(f, inst, "!((", "!=", "ne"), | |
| 2376 | 2404 | |
| 2377 | 2405 | .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}), |
| 2378 | 2406 | .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst), |
| ... | ... | @@ -2468,7 +2496,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 2468 | 2496 | .float_to_int, |
| 2469 | 2497 | .fptrunc, |
| 2470 | 2498 | .fpext, |
| 2471 | => try airSimpleCast(f, inst), | |
| 2499 | => try airFloatCast(f, inst), | |
| 2472 | 2500 | |
| 2473 | 2501 | .ptrtoint => try airPtrToInt(f, inst), |
| 2474 | 2502 | |
| ... | ... | @@ -2973,8 +3001,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2973 | 3001 | |
| 2974 | 3002 | const src_bits = src_ty.bitSize(target); |
| 2975 | 3003 | |
| 2976 | const Limb = std.math.big.Limb; | |
| 2977 | const ExpectedContents = [BigInt.Managed.default_capacity]Limb; | |
| 3004 | const ExpectedContents = [BigInt.Managed.default_capacity]BigIntLimb; | |
| 2978 | 3005 | var stack align(@alignOf(ExpectedContents)) = |
| 2979 | 3006 | std.heap.stackFallback(@sizeOf(ExpectedContents), f.object.dg.gpa); |
| 2980 | 3007 | |
| ... | ... | @@ -3003,6 +3030,11 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3003 | 3030 | try writer.writeAll("(("); |
| 3004 | 3031 | try f.renderTypecast(writer, host_ty); |
| 3005 | 3032 | try writer.writeByte(')'); |
| 3033 | if (src_ty.isPtrAtRuntime()) { | |
| 3034 | try writer.writeByte('('); | |
| 3035 | try f.renderTypecast(writer, Type.usize); | |
| 3036 | try writer.writeByte(')'); | |
| 3037 | } | |
| 3006 | 3038 | try f.writeCValue(writer, src_val, .Other); |
| 3007 | 3039 | try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); |
| 3008 | 3040 | } else { |
| ... | ... | @@ -3081,7 +3113,7 @@ fn airBinOp( |
| 3081 | 3113 | |
| 3082 | 3114 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 3083 | 3115 | const target = f.object.dg.module.getTarget(); |
| 3084 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) | |
| 3116 | if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat()) | |
| 3085 | 3117 | return try airBinBuiltinCall(f, inst, operation, info); |
| 3086 | 3118 | |
| 3087 | 3119 | const inst_ty = f.air.typeOfIndex(inst); |
| ... | ... | @@ -3102,7 +3134,7 @@ fn airBinOp( |
| 3102 | 3134 | return local; |
| 3103 | 3135 | } |
| 3104 | 3136 | |
| 3105 | fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue { | |
| 3137 | fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8, operation: []const u8) !CValue { | |
| 3106 | 3138 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3107 | 3139 | |
| 3108 | 3140 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| ... | ... | @@ -3110,7 +3142,9 @@ fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue { |
| 3110 | 3142 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 3111 | 3143 | const target = f.object.dg.module.getTarget(); |
| 3112 | 3144 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) |
| 3113 | return try airCmpBuiltinCall(f, inst, operator); | |
| 3145 | return try airCmpBuiltinCall(f, inst, operator, "cmp"); | |
| 3146 | if (operand_ty.isRuntimeFloat()) | |
| 3147 | return try airCmpBuiltinCall(f, inst, operator, operation); | |
| 3114 | 3148 | |
| 3115 | 3149 | const inst_ty = f.air.typeOfIndex(inst); |
| 3116 | 3150 | const lhs = try f.resolveInst(bin_op.lhs); |
| ... | ... | @@ -3134,11 +3168,20 @@ fn airEquality( |
| 3134 | 3168 | f: *Function, |
| 3135 | 3169 | inst: Air.Inst.Index, |
| 3136 | 3170 | negate_prefix: []const u8, |
| 3137 | eq_op_str: []const u8, | |
| 3171 | operator: []const u8, | |
| 3172 | operation: []const u8, | |
| 3138 | 3173 | ) !CValue { |
| 3139 | 3174 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3140 | 3175 | |
| 3141 | 3176 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3177 | ||
| 3178 | const operand_ty = f.air.typeOf(bin_op.lhs); | |
| 3179 | const target = f.object.dg.module.getTarget(); | |
| 3180 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) | |
| 3181 | return try airCmpBuiltinCall(f, inst, operator, "cmp"); | |
| 3182 | if (operand_ty.isRuntimeFloat()) | |
| 3183 | return try airCmpBuiltinCall(f, inst, operator, operation); | |
| 3184 | ||
| 3142 | 3185 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3143 | 3186 | const rhs = try f.resolveInst(bin_op.rhs); |
| 3144 | 3187 | |
| ... | ... | @@ -3148,8 +3191,7 @@ fn airEquality( |
| 3148 | 3191 | |
| 3149 | 3192 | try writer.writeAll(" = "); |
| 3150 | 3193 | |
| 3151 | const lhs_ty = f.air.typeOf(bin_op.lhs); | |
| 3152 | if (lhs_ty.tag() == .optional) { | |
| 3194 | if (operand_ty.tag() == .optional) { | |
| 3153 | 3195 | // (A && B) || (C && (A == B)) |
| 3154 | 3196 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload |
| 3155 | 3197 | |
| ... | ... | @@ -3172,7 +3214,7 @@ fn airEquality( |
| 3172 | 3214 | |
| 3173 | 3215 | try f.writeCValue(writer, lhs, .Other); |
| 3174 | 3216 | try writer.writeByte(' '); |
| 3175 | try writer.writeAll(eq_op_str); | |
| 3217 | try writer.writeAll(operator); | |
| 3176 | 3218 | try writer.writeByte(' '); |
| 3177 | 3219 | try f.writeCValue(writer, rhs, .Other); |
| 3178 | 3220 | try writer.writeAll(";\n"); |
| ... | ... | @@ -3231,15 +3273,22 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3231 | 3273 | return local; |
| 3232 | 3274 | } |
| 3233 | 3275 | |
| 3234 | fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | |
| 3276 | fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue { | |
| 3235 | 3277 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3236 | 3278 | |
| 3237 | 3279 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3280 | ||
| 3281 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3282 | const target = f.object.dg.module.getTarget(); | |
| 3283 | if (inst_ty.isInt() and inst_ty.bitSize(target) > 64) | |
| 3284 | return try airBinBuiltinCall(f, inst, operation[1..], .None); | |
| 3285 | if (inst_ty.isRuntimeFloat()) | |
| 3286 | return try airBinFloatOp(f, inst, operation); | |
| 3287 | ||
| 3238 | 3288 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3239 | 3289 | const rhs = try f.resolveInst(bin_op.rhs); |
| 3240 | 3290 | |
| 3241 | 3291 | const writer = f.object.writer(); |
| 3242 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3243 | 3292 | const local = try f.allocLocal(inst_ty, .Const); |
| 3244 | 3293 | |
| 3245 | 3294 | // (lhs <> rhs) ? lhs : rhs |
| ... | ... | @@ -4518,19 +4567,44 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4518 | 4567 | return local; |
| 4519 | 4568 | } |
| 4520 | 4569 | |
| 4521 | /// Emits a local variable with the result type and initializes it | |
| 4522 | /// with the operand. | |
| 4523 | fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 4570 | fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 4524 | 4571 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4525 | 4572 | |
| 4526 | 4573 | const inst_ty = f.air.typeOfIndex(inst); |
| 4527 | const local = try f.allocLocal(inst_ty, .Const); | |
| 4528 | 4574 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4529 | const writer = f.object.writer(); | |
| 4530 | 4575 | const operand = try f.resolveInst(ty_op.operand); |
| 4576 | const operand_ty = f.air.typeOf(ty_op.operand); | |
| 4577 | const target = f.object.dg.module.getTarget(); | |
| 4578 | const operation = if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat()) | |
| 4579 | if (inst_ty.floatBits(target) < operand_ty.floatBits(target)) "trunc" else "extend" | |
| 4580 | else if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) | |
| 4581 | if (inst_ty.isSignedInt()) "fix" else "fixuns" | |
| 4582 | else if (inst_ty.isRuntimeFloat() and operand_ty.isInt()) | |
| 4583 | if (operand_ty.isSignedInt()) "float" else "floatun" | |
| 4584 | else | |
| 4585 | unreachable; | |
| 4586 | ||
| 4587 | const local = try f.allocLocal(inst_ty, .Const); | |
| 4588 | const writer = f.object.writer(); | |
| 4531 | 4589 | |
| 4532 | 4590 | try writer.writeAll(" = "); |
| 4533 | try f.writeCValue(writer, operand, .Other); | |
| 4591 | if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) { | |
| 4592 | try writer.writeAll("zig_wrap_"); | |
| 4593 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | |
| 4594 | try writer.writeByte('('); | |
| 4595 | } | |
| 4596 | try writer.writeAll("__"); | |
| 4597 | try writer.writeAll(operation); | |
| 4598 | try writer.writeAll(compilerRtAbbrev(operand_ty, target)); | |
| 4599 | try writer.writeAll(compilerRtAbbrev(inst_ty, target)); | |
| 4600 | if (inst_ty.isRuntimeFloat() and operand_ty.isRuntimeFloat()) try writer.writeByte('2'); | |
| 4601 | try writer.writeByte('('); | |
| 4602 | try f.writeCValue(writer, operand, .FunctionArgument); | |
| 4603 | try writer.writeByte(')'); | |
| 4604 | if (inst_ty.isInt() and operand_ty.isRuntimeFloat()) { | |
| 4605 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits); | |
| 4606 | try writer.writeByte(')'); | |
| 4607 | } | |
| 4534 | 4608 | try writer.writeAll(";\n"); |
| 4535 | 4609 | return local; |
| 4536 | 4610 | } |
| ... | ... | @@ -4604,7 +4678,12 @@ fn airBinBuiltinCall( |
| 4604 | 4678 | return local; |
| 4605 | 4679 | } |
| 4606 | 4680 | |
| 4607 | fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue { | |
| 4681 | fn airCmpBuiltinCall( | |
| 4682 | f: *Function, | |
| 4683 | inst: Air.Inst.Index, | |
| 4684 | operator: []const u8, | |
| 4685 | operation: []const u8, | |
| 4686 | ) !CValue { | |
| 4608 | 4687 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4609 | 4688 | |
| 4610 | 4689 | const inst_ty = f.air.typeOfIndex(inst); |
| ... | ... | @@ -4613,7 +4692,9 @@ fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) ! |
| 4613 | 4692 | |
| 4614 | 4693 | const local = try f.allocLocal(inst_ty, .Const); |
| 4615 | 4694 | const writer = f.object.writer(); |
| 4616 | try writer.writeAll(" = zig_cmp_"); | |
| 4695 | try writer.writeAll(" = zig_"); | |
| 4696 | try writer.writeAll(operation); | |
| 4697 | try writer.writeByte('_'); | |
| 4617 | 4698 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); |
| 4618 | 4699 | try writer.writeByte('('); |
| 4619 | 4700 | try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument); |
| ... | ... | @@ -5045,6 +5126,14 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5045 | 5126 | try writer.writeAll("(("); |
| 5046 | 5127 | try f.renderTypecast(writer, inst_ty); |
| 5047 | 5128 | try writer.writeByte(')'); |
| 5129 | if (field_ty.isPtrAtRuntime()) { | |
| 5130 | try writer.writeByte('('); | |
| 5131 | try f.renderTypecast(writer, switch (int_info.signedness) { | |
| 5132 | .unsigned => Type.usize, | |
| 5133 | .signed => Type.isize, | |
| 5134 | }); | |
| 5135 | try writer.writeByte(')'); | |
| 5136 | } | |
| 5048 | 5137 | try f.writeCValue(writer, try f.resolveInst(element), .Other); |
| 5049 | 5138 | try writer.writeAll(", "); |
| 5050 | 5139 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); |
| ... | ... | @@ -5157,17 +5246,21 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5157 | 5246 | return local; |
| 5158 | 5247 | } |
| 5159 | 5248 | |
| 5160 | fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 5249 | fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 5161 | 5250 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 5162 | 5251 | |
| 5163 | const un_op = f.air.instructions.items(.data)[inst].un_op; | |
| 5164 | const writer = f.object.writer(); | |
| 5165 | 5252 | const inst_ty = f.air.typeOfIndex(inst); |
| 5253 | const un_op = f.air.instructions.items(.data)[inst].un_op; | |
| 5166 | 5254 | const operand = try f.resolveInst(un_op); |
| 5255 | const operand_ty = f.air.typeOf(un_op); | |
| 5256 | ||
| 5167 | 5257 | const local = try f.allocLocal(inst_ty, .Const); |
| 5168 | try writer.writeAll(" = -"); | |
| 5169 | try f.writeCValue(writer, operand, .Other); | |
| 5170 | try writer.writeAll(";\n"); | |
| 5258 | const writer = f.object.writer(); | |
| 5259 | try writer.writeAll(" = zig_neg_"); | |
| 5260 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | |
| 5261 | try writer.writeByte('('); | |
| 5262 | try f.writeCValue(writer, operand, .FunctionArgument); | |
| 5263 | try writer.writeAll(");\n"); | |
| 5171 | 5264 | return local; |
| 5172 | 5265 | } |
| 5173 | 5266 | |
| ... | ... | @@ -5178,7 +5271,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal |
| 5178 | 5271 | const inst_ty = f.air.typeOfIndex(inst); |
| 5179 | 5272 | const operand = try f.resolveInst(un_op); |
| 5180 | 5273 | const local = try f.allocLocal(inst_ty, .Const); |
| 5181 | try writer.writeAll(" = zig_builtin_"); | |
| 5274 | try writer.writeAll(" = zig_libc_name_"); | |
| 5182 | 5275 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); |
| 5183 | 5276 | try writer.writeByte('('); |
| 5184 | 5277 | try writer.writeAll(operation); |
| ... | ... | @@ -5196,7 +5289,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa |
| 5196 | 5289 | const lhs = try f.resolveInst(bin_op.lhs); |
| 5197 | 5290 | const rhs = try f.resolveInst(bin_op.rhs); |
| 5198 | 5291 | const local = try f.allocLocal(inst_ty, .Const); |
| 5199 | try writer.writeAll(" = zig_builtin_"); | |
| 5292 | try writer.writeAll(" = zig_libc_name_"); | |
| 5200 | 5293 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); |
| 5201 | 5294 | try writer.writeByte('('); |
| 5202 | 5295 | try writer.writeAll(operation); |
| ... | ... | @@ -5218,7 +5311,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5218 | 5311 | const addend = try f.resolveInst(pl_op.operand); |
| 5219 | 5312 | const writer = f.object.writer(); |
| 5220 | 5313 | const local = try f.allocLocal(inst_ty, .Const); |
| 5221 | try writer.writeAll(" = zig_builtin_"); | |
| 5314 | try writer.writeAll(" = zig_libc_name_"); | |
| 5222 | 5315 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); |
| 5223 | 5316 | try writer.writeAll("(fma)("); |
| 5224 | 5317 | try f.writeCValue(writer, mulend1, .FunctionArgument); |
| ... | ... | @@ -5328,6 +5421,22 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 { |
| 5328 | 5421 | }; |
| 5329 | 5422 | } |
| 5330 | 5423 | |
| 5424 | fn compilerRtAbbrev(ty: Type, target: std.Target) []const u8 { | |
| 5425 | return if (ty.isInt()) switch (ty.intInfo(target).bits) { | |
| 5426 | 1...32 => "si", | |
| 5427 | 33...64 => "di", | |
| 5428 | 65...128 => "ti", | |
| 5429 | else => unreachable, | |
| 5430 | } else if (ty.isRuntimeFloat()) switch (ty.floatBits(target)) { | |
| 5431 | 16 => "hf", | |
| 5432 | 32 => "sf", | |
| 5433 | 64 => "df", | |
| 5434 | 80 => "xf", | |
| 5435 | 128 => "tf", | |
| 5436 | else => unreachable, | |
| 5437 | } else unreachable; | |
| 5438 | } | |
| 5439 | ||
| 5331 | 5440 | fn formatStringLiteral( |
| 5332 | 5441 | str: []const u8, |
| 5333 | 5442 | comptime fmt: []const u8, |
| ... | ... | @@ -5356,8 +5465,10 @@ fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) { |
| 5356 | 5465 | return .{ .data = str }; |
| 5357 | 5466 | } |
| 5358 | 5467 | |
| 5359 | fn undefPattern(comptime T: type) T { | |
| 5360 | return (1 << (@bitSizeOf(T) | 1)) / 3; | |
| 5468 | fn undefPattern(comptime IntType: type) IntType { | |
| 5469 | const int_info = @typeInfo(IntType).Int; | |
| 5470 | const UnsignedType = std.meta.Int(.unsigned, int_info.bits); | |
| 5471 | return @bitCast(IntType, @as(UnsignedType, (1 << (int_info.bits | 1)) / 3)); | |
| 5361 | 5472 | } |
| 5362 | 5473 | |
| 5363 | 5474 | const FormatIntLiteralContext = struct { |
| ... | ... | @@ -5374,30 +5485,29 @@ fn formatIntLiteral( |
| 5374 | 5485 | const target = data.mod.getTarget(); |
| 5375 | 5486 | const int_info = data.ty.intInfo(target); |
| 5376 | 5487 | |
| 5377 | const Limb = std.math.big.Limb; | |
| 5378 | 5488 | const ExpectedContents = struct { |
| 5379 | 5489 | const base = 10; |
| 5380 | 5490 | const limbs_count_128 = BigInt.calcTwosCompLimbCount(128); |
| 5381 | 5491 | const expected_needed_limbs_count = BigInt.calcToStringLimbsBufferLen(limbs_count_128, base); |
| 5382 | 5492 | const worst_case_int = BigInt.Const{ |
| 5383 | .limbs = &([1]Limb{std.math.maxInt(Limb)} ** expected_needed_limbs_count), | |
| 5493 | .limbs = &([1]BigIntLimb{std.math.maxInt(BigIntLimb)} ** expected_needed_limbs_count), | |
| 5384 | 5494 | .positive = false, |
| 5385 | 5495 | }; |
| 5386 | 5496 | |
| 5387 | undef_limbs: [limbs_count_128]Limb, | |
| 5388 | wrap_limbs: [limbs_count_128]Limb, | |
| 5497 | undef_limbs: [limbs_count_128]BigIntLimb, | |
| 5498 | wrap_limbs: [limbs_count_128]BigIntLimb, | |
| 5389 | 5499 | }; |
| 5390 | 5500 | var stack align(@alignOf(ExpectedContents)) = |
| 5391 | 5501 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.mod.gpa); |
| 5392 | 5502 | const allocator = stack.get(); |
| 5393 | 5503 | |
| 5394 | var undef_limbs: []Limb = &.{}; | |
| 5504 | var undef_limbs: []BigIntLimb = &.{}; | |
| 5395 | 5505 | defer allocator.free(undef_limbs); |
| 5396 | 5506 | |
| 5397 | 5507 | var int_buf: Value.BigIntSpace = undefined; |
| 5398 | 5508 | const int = if (data.val.isUndefDeep()) blk: { |
| 5399 | undef_limbs = try allocator.alloc(Limb, BigInt.calcTwosCompLimbCount(int_info.bits)); | |
| 5400 | std.mem.set(Limb, undef_limbs, undefPattern(Limb)); | |
| 5509 | undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(int_info.bits)); | |
| 5510 | std.mem.set(BigIntLimb, undef_limbs, undefPattern(BigIntLimb)); | |
| 5401 | 5511 | |
| 5402 | 5512 | var undef_int = BigInt.Mutable{ |
| 5403 | 5513 | .limbs = undef_limbs, |
| ... | ... | @@ -5410,10 +5520,10 @@ fn formatIntLiteral( |
| 5410 | 5520 | assert(int.fitsInTwosComp(int_info.signedness, int_info.bits)); |
| 5411 | 5521 | |
| 5412 | 5522 | const c_bits = toCIntBits(int_info.bits) orelse unreachable; |
| 5413 | var one_limbs: [BigInt.calcLimbLen(1)]Limb = undefined; | |
| 5523 | var one_limbs: [BigInt.calcLimbLen(1)]BigIntLimb = undefined; | |
| 5414 | 5524 | const one = BigInt.Mutable.init(&one_limbs, 1).toConst(); |
| 5415 | 5525 | |
| 5416 | const wrap_limbs = try allocator.alloc(Limb, BigInt.calcTwosCompLimbCount(c_bits)); | |
| 5526 | const wrap_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)); | |
| 5417 | 5527 | defer allocator.free(wrap_limbs); |
| 5418 | 5528 | var wrap = BigInt.Mutable{ .limbs = wrap_limbs, .len = undefined, .positive = undefined }; |
| 5419 | 5529 | if (wrap.addWrap(int, one, int_info.signedness, c_bits) or |
| ... | ... | @@ -5439,7 +5549,7 @@ fn formatIntLiteral( |
| 5439 | 5549 | else => try writer.print("zig_as_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }), |
| 5440 | 5550 | } |
| 5441 | 5551 | |
| 5442 | const limbs_count_64 = @divExact(64, @bitSizeOf(Limb)); | |
| 5552 | const limbs_count_64 = @divExact(64, @bitSizeOf(BigIntLimb)); | |
| 5443 | 5553 | if (c_bits <= 64) { |
| 5444 | 5554 | var base: u8 = undefined; |
| 5445 | 5555 | var case: std.fmt.Case = undefined; |
| ... | ... | @@ -5471,7 +5581,7 @@ fn formatIntLiteral( |
| 5471 | 5581 | } |
| 5472 | 5582 | |
| 5473 | 5583 | var str: [64]u8 = undefined; |
| 5474 | var limbs_buf: [BigInt.calcToStringLimbsBufferLen(limbs_count_64, 10)]Limb = undefined; | |
| 5584 | var limbs_buf: [BigInt.calcToStringLimbsBufferLen(limbs_count_64, 10)]BigIntLimb = undefined; | |
| 5475 | 5585 | try writer.writeAll(str[0..int.abs().toString(&str, base, case, &limbs_buf)]); |
| 5476 | 5586 | } else { |
| 5477 | 5587 | assert(c_bits == 128); |
test/behavior/atomics.zig+10-2| ... | ... | @@ -220,8 +220,8 @@ test "atomicrmw with floats" { |
| 220 | 220 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 221 | 221 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 222 | 222 | |
| 223 | if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm) and | |
| 224 | builtin.cpu.arch == .aarch64) | |
| 223 | if ((builtin.zig_backend == .stage1 or builtin.zig_backend == .stage2_llvm or | |
| 224 | builtin.zig_backend == .stage2_c) and builtin.cpu.arch == .aarch64) | |
| 225 | 225 | { |
| 226 | 226 | // https://github.com/ziglang/zig/issues/10627 |
| 227 | 227 | return error.SkipZigTest; |
| ... | ... | @@ -248,6 +248,10 @@ test "atomicrmw with ints" { |
| 248 | 248 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 249 | 249 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 250 | 250 | |
| 251 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) { | |
| 252 | return error.SkipZigTest; | |
| 253 | } | |
| 254 | ||
| 251 | 255 | try testAtomicRmwInt(); |
| 252 | 256 | comptime try testAtomicRmwInt(); |
| 253 | 257 | } |
| ... | ... | @@ -282,6 +286,10 @@ test "atomics with different types" { |
| 282 | 286 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 283 | 287 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 284 | 288 | |
| 289 | if (builtin.zig_backend == .stage2_c and builtin.cpu.arch == .aarch64) { | |
| 290 | return error.SkipZigTest; | |
| 291 | } | |
| 292 | ||
| 285 | 293 | try testAtomicsWithType(bool, true, false); |
| 286 | 294 | |
| 287 | 295 | try testAtomicsWithType(u1, 0, 1); |
test/tests.zig-4| ... | ... | @@ -678,10 +678,6 @@ pub fn addPkgTests( |
| 678 | 678 | // https://github.com/ziglang/zig/issues/12415 |
| 679 | 679 | continue; |
| 680 | 680 | } |
| 681 | if (backend == .stage2_c and builtin.cpu.arch == .aarch64) { | |
| 682 | // https://github.com/ziglang/zig/issues/13357 | |
| 683 | continue; | |
| 684 | } | |
| 685 | 681 | } |
| 686 | 682 | |
| 687 | 683 | const libc_prefix = if (test_target.target.getOs().requiresLibC()) |