| author | |
| committer | |
| log | 6a98bf3dba6f3ed5b40fe7899899e2a792028be4 |
| tree | 9c4e4eb61e70ad0853119c12882c108631b7ad4b |
| parent | cf46cd5f2b0f87430185c5d89056321d16f42d58 |
* add u128 and i128 integer types
* add f128 floating point type
* implement big integer multiplication (See #405)27 files changed, 588 insertions(+), 22 deletions(-)
CMakeLists.txt+15-3| ... | @@ -239,10 +239,10 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/dwarf.zig" DESTINATION "${ZIG_STD_DEST}") | ... | @@ -239,10 +239,10 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/dwarf.zig" DESTINATION "${ZIG_STD_DEST}") |
| 239 | install(FILES "${CMAKE_SOURCE_DIR}/std/elf.zig" DESTINATION "${ZIG_STD_DEST}") | 239 | install(FILES "${CMAKE_SOURCE_DIR}/std/elf.zig" DESTINATION "${ZIG_STD_DEST}") |
| 240 | install(FILES "${CMAKE_SOURCE_DIR}/std/empty.zig" DESTINATION "${ZIG_STD_DEST}") | 240 | install(FILES "${CMAKE_SOURCE_DIR}/std/empty.zig" DESTINATION "${ZIG_STD_DEST}") |
| 241 | install(FILES "${CMAKE_SOURCE_DIR}/std/endian.zig" DESTINATION "${ZIG_STD_DEST}") | 241 | install(FILES "${CMAKE_SOURCE_DIR}/std/endian.zig" DESTINATION "${ZIG_STD_DEST}") |
| 242 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/index.zig" DESTINATION "${ZIG_STD_DEST}/fmt") | ||
| 243 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/index.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol") | ||
| 244 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/enum3.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol") | 242 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/enum3.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol") |
| 243 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/index.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol") | ||
| 245 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/lookup.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol") | 244 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/errol/lookup.zig" DESTINATION "${ZIG_STD_DEST}/fmt/errol") |
| 245 | install(FILES "${CMAKE_SOURCE_DIR}/std/fmt/index.zig" DESTINATION "${ZIG_STD_DEST}/fmt") | ||
| 246 | install(FILES "${CMAKE_SOURCE_DIR}/std/hash_map.zig" DESTINATION "${ZIG_STD_DEST}") | 246 | install(FILES "${CMAKE_SOURCE_DIR}/std/hash_map.zig" DESTINATION "${ZIG_STD_DEST}") |
| 247 | install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}") | 247 | install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}") |
| 248 | install(FILES "${CMAKE_SOURCE_DIR}/std/io.zig" DESTINATION "${ZIG_STD_DEST}") | 248 | install(FILES "${CMAKE_SOURCE_DIR}/std/io.zig" DESTINATION "${ZIG_STD_DEST}") |
| ... | @@ -303,15 +303,27 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux.zig" DESTINATION "${ZIG_STD_DEST | ... | @@ -303,15 +303,27 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux.zig" DESTINATION "${ZIG_STD_DEST |
| 303 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}/os") | 303 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}/os") |
| 304 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}/os") | 304 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}/os") |
| 305 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/path.zig" DESTINATION "${ZIG_STD_DEST}/os") | 305 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/path.zig" DESTINATION "${ZIG_STD_DEST}/os") |
| 306 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/index.zig" DESTINATION "${ZIG_STD_DEST}/os/windows") | ||
| 307 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/error.zig" DESTINATION "${ZIG_STD_DEST}/os/windows") | 306 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/error.zig" DESTINATION "${ZIG_STD_DEST}/os/windows") |
| 307 | install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/index.zig" DESTINATION "${ZIG_STD_DEST}/os/windows") | ||
| 308 | install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") | 308 | install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") |
| 309 | install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}") | 309 | install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}") |
| 310 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") | 310 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 311 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special") | 311 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 312 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") | 312 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 313 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") | 313 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 314 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixuint.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 315 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfdi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 316 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfsi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 317 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfti.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 318 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunssfdi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 319 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunssfsi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 320 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunssfti.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 321 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunstfdi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 322 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunstfsi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 323 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunstfti.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 314 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/index.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | 324 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/index.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") |
| 325 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/udivti3.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 326 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/umodti3.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 315 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") | 327 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 316 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/zigrt.zig" DESTINATION "${ZIG_STD_DEST}/special") | 328 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/zigrt.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 317 | 329 |
src/all_types.hpp+4-1| ... | @@ -1386,7 +1386,7 @@ struct CodeGen { | ... | @@ -1386,7 +1386,7 @@ struct CodeGen { |
| 1386 | 1386 | ||
| 1387 | struct { | 1387 | struct { |
| 1388 | TypeTableEntry *entry_bool; | 1388 | TypeTableEntry *entry_bool; |
| 1389 | TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64] | 1389 | TypeTableEntry *entry_int[2][5]; // [signed,unsigned][8,16,32,64,128] |
| 1390 | TypeTableEntry *entry_c_int[CIntTypeCount]; | 1390 | TypeTableEntry *entry_c_int[CIntTypeCount]; |
| 1391 | TypeTableEntry *entry_c_longdouble; | 1391 | TypeTableEntry *entry_c_longdouble; |
| 1392 | TypeTableEntry *entry_c_void; | 1392 | TypeTableEntry *entry_c_void; |
| ... | @@ -1394,14 +1394,17 @@ struct CodeGen { | ... | @@ -1394,14 +1394,17 @@ struct CodeGen { |
| 1394 | TypeTableEntry *entry_u16; | 1394 | TypeTableEntry *entry_u16; |
| 1395 | TypeTableEntry *entry_u32; | 1395 | TypeTableEntry *entry_u32; |
| 1396 | TypeTableEntry *entry_u64; | 1396 | TypeTableEntry *entry_u64; |
| 1397 | TypeTableEntry *entry_u128; | ||
| 1397 | TypeTableEntry *entry_i8; | 1398 | TypeTableEntry *entry_i8; |
| 1398 | TypeTableEntry *entry_i16; | 1399 | TypeTableEntry *entry_i16; |
| 1399 | TypeTableEntry *entry_i32; | 1400 | TypeTableEntry *entry_i32; |
| 1400 | TypeTableEntry *entry_i64; | 1401 | TypeTableEntry *entry_i64; |
| 1402 | TypeTableEntry *entry_i128; | ||
| 1401 | TypeTableEntry *entry_isize; | 1403 | TypeTableEntry *entry_isize; |
| 1402 | TypeTableEntry *entry_usize; | 1404 | TypeTableEntry *entry_usize; |
| 1403 | TypeTableEntry *entry_f32; | 1405 | TypeTableEntry *entry_f32; |
| 1404 | TypeTableEntry *entry_f64; | 1406 | TypeTableEntry *entry_f64; |
| 1407 | TypeTableEntry *entry_f128; | ||
| 1405 | TypeTableEntry *entry_void; | 1408 | TypeTableEntry *entry_void; |
| 1406 | TypeTableEntry *entry_unreachable; | 1409 | TypeTableEntry *entry_unreachable; |
| 1407 | TypeTableEntry *entry_type; | 1410 | TypeTableEntry *entry_type; |
src/analyze.cpp+2| ... | @@ -3085,6 +3085,8 @@ TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_b | ... | @@ -3085,6 +3085,8 @@ TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_b |
| 3085 | index = 2; | 3085 | index = 2; |
| 3086 | } else if (size_in_bits == 64) { | 3086 | } else if (size_in_bits == 64) { |
| 3087 | index = 3; | 3087 | index = 3; |
| 3088 | } else if (size_in_bits == 128) { | ||
| 3089 | index = 4; | ||
| 3088 | } else { | 3090 | } else { |
| 3089 | return nullptr; | 3091 | return nullptr; |
| 3090 | } | 3092 | } |
src/bigint.cpp+70-14| ... | @@ -373,7 +373,6 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { | ... | @@ -373,7 +373,6 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 373 | bigint_normalize(dest); | 373 | bigint_normalize(dest); |
| 374 | return; | 374 | return; |
| 375 | } | 375 | } |
| 376 | // TODO this code path is untested | ||
| 377 | size_t i = 1; | 376 | size_t i = 1; |
| 378 | uint64_t first_digit = dest->data.digit; | 377 | uint64_t first_digit = dest->data.digit; |
| 379 | dest->data.digits = allocate_nonzero<uint64_t>(max(op1->digit_count, op2->digit_count) + 1); | 378 | dest->data.digits = allocate_nonzero<uint64_t>(max(op1->digit_count, op2->digit_count) + 1); |
| ... | @@ -397,17 +396,14 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { | ... | @@ -397,17 +396,14 @@ void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 397 | } | 396 | } |
| 398 | 397 | ||
| 399 | dest->data.digits[i] = x; | 398 | dest->data.digits[i] = x; |
| 400 | x += 1; | 399 | i += 1; |
| 401 | 400 | ||
| 402 | if (!found_digit) { | 401 | if (!found_digit) { |
| 403 | break; | 402 | dest->digit_count = i; |
| 403 | bigint_normalize(dest); | ||
| 404 | return; | ||
| 404 | } | 405 | } |
| 405 | } | 406 | } |
| 406 | if (overflow > 0) { | ||
| 407 | dest->data.digits[i] = overflow; | ||
| 408 | } | ||
| 409 | bigint_normalize(dest); | ||
| 410 | return; | ||
| 411 | } | 407 | } |
| 412 | const BigInt *op_pos; | 408 | const BigInt *op_pos; |
| 413 | const BigInt *op_neg; | 409 | const BigInt *op_neg; |
| ... | @@ -500,12 +496,49 @@ static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *car | ... | @@ -500,12 +496,49 @@ static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *car |
| 500 | *carry = 0; | 496 | *carry = 0; |
| 501 | return; | 497 | return; |
| 502 | } | 498 | } |
| 503 | zig_panic("TODO bigint_mul with big numbers"); | ||
| 504 | 499 | ||
| 505 | //unsigned __int128 big_x = x; | 500 | unsigned __int128 big_x = x; |
| 506 | //unsigned __int128 big_y = y; | 501 | unsigned __int128 big_y = y; |
| 507 | //unsigned __int128 big_result = big_x * big_y; | 502 | unsigned __int128 big_result = big_x * big_y; |
| 508 | //*carry = big_result >> 64; | 503 | *carry = big_result >> 64; |
| 504 | } | ||
| 505 | |||
| 506 | static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) { | ||
| 507 | bigint_init_unsigned(dest, 0); | ||
| 508 | |||
| 509 | BigInt bi_64; | ||
| 510 | bigint_init_unsigned(&bi_64, 64); | ||
| 511 | |||
| 512 | const uint64_t *op_digits = bigint_ptr(op); | ||
| 513 | size_t i = op->digit_count - 1; | ||
| 514 | |||
| 515 | for (;;) { | ||
| 516 | BigInt shifted; | ||
| 517 | bigint_shl(&shifted, dest, &bi_64); | ||
| 518 | |||
| 519 | uint64_t result_scalar; | ||
| 520 | uint64_t carry_scalar; | ||
| 521 | mul_overflow(scalar, op_digits[i], &result_scalar, &carry_scalar); | ||
| 522 | |||
| 523 | BigInt result; | ||
| 524 | bigint_init_unsigned(&result, result_scalar); | ||
| 525 | |||
| 526 | BigInt carry; | ||
| 527 | bigint_init_unsigned(&carry, carry_scalar); | ||
| 528 | |||
| 529 | BigInt carry_shifted; | ||
| 530 | bigint_shl(&carry_shifted, &carry, &bi_64); | ||
| 531 | |||
| 532 | BigInt tmp; | ||
| 533 | bigint_add(&tmp, &shifted, &carry_shifted); | ||
| 534 | |||
| 535 | bigint_add(dest, &tmp, &result); | ||
| 536 | |||
| 537 | if (i == 0) { | ||
| 538 | break; | ||
| 539 | } | ||
| 540 | i -= 1; | ||
| 541 | } | ||
| 509 | } | 542 | } |
| 510 | 543 | ||
| 511 | void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2) { | 544 | void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| ... | @@ -523,7 +556,30 @@ void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2) { | ... | @@ -523,7 +556,30 @@ void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2) { |
| 523 | bigint_normalize(dest); | 556 | bigint_normalize(dest); |
| 524 | return; | 557 | return; |
| 525 | } | 558 | } |
| 526 | zig_panic("TODO bigint_mul with big numbers"); | 559 | |
| 560 | bigint_init_unsigned(dest, 0); | ||
| 561 | |||
| 562 | BigInt bi_64; | ||
| 563 | bigint_init_unsigned(&bi_64, 64); | ||
| 564 | |||
| 565 | size_t i = op2->digit_count - 1; | ||
| 566 | for (;;) { | ||
| 567 | BigInt shifted; | ||
| 568 | bigint_shl(&shifted, dest, &bi_64); | ||
| 569 | |||
| 570 | BigInt scalar_result; | ||
| 571 | mul_scalar(&scalar_result, op1, op2_digits[i]); | ||
| 572 | |||
| 573 | bigint_add(dest, &scalar_result, &shifted); | ||
| 574 | |||
| 575 | if (i == 0) { | ||
| 576 | break; | ||
| 577 | } | ||
| 578 | i -= 1; | ||
| 579 | } | ||
| 580 | |||
| 581 | dest->is_negative = (op1->is_negative != op2->is_negative); | ||
| 582 | bigint_normalize(dest); | ||
| 527 | } | 583 | } |
| 528 | 584 | ||
| 529 | void bigint_mul_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed) { | 585 | void bigint_mul_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t bit_count, bool is_signed) { |
src/codegen.cpp+16| ... | @@ -4208,6 +4208,7 @@ static const uint8_t int_sizes_in_bits[] = { | ... | @@ -4208,6 +4208,7 @@ static const uint8_t int_sizes_in_bits[] = { |
| 4208 | 16, | 4208 | 16, |
| 4209 | 32, | 4209 | 32, |
| 4210 | 64, | 4210 | 64, |
| 4211 | 128, | ||
| 4211 | }; | 4212 | }; |
| 4212 | 4213 | ||
| 4213 | struct CIntTypeInfo { | 4214 | struct CIntTypeInfo { |
| ... | @@ -4390,6 +4391,19 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -4390,6 +4391,19 @@ static void define_builtin_types(CodeGen *g) { |
| 4390 | g->builtin_types.entry_f64 = entry; | 4391 | g->builtin_types.entry_f64 = entry; |
| 4391 | g->primitive_type_table.put(&entry->name, entry); | 4392 | g->primitive_type_table.put(&entry->name, entry); |
| 4392 | } | 4393 | } |
| 4394 | { | ||
| 4395 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); | ||
| 4396 | entry->type_ref = LLVMFP128Type(); | ||
| 4397 | buf_init_from_str(&entry->name, "f128"); | ||
| 4398 | entry->data.floating.bit_count = 128; | ||
| 4399 | |||
| 4400 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); | ||
| 4401 | entry->di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), | ||
| 4402 | debug_size_in_bits, | ||
| 4403 | ZigLLVMEncoding_DW_ATE_float()); | ||
| 4404 | g->builtin_types.entry_f128 = entry; | ||
| 4405 | g->primitive_type_table.put(&entry->name, entry); | ||
| 4406 | } | ||
| 4393 | { | 4407 | { |
| 4394 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); | 4408 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat); |
| 4395 | entry->type_ref = LLVMX86FP80Type(); | 4409 | entry->type_ref = LLVMX86FP80Type(); |
| ... | @@ -4435,10 +4449,12 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -4435,10 +4449,12 @@ static void define_builtin_types(CodeGen *g) { |
| 4435 | g->builtin_types.entry_u16 = get_int_type(g, false, 16); | 4449 | g->builtin_types.entry_u16 = get_int_type(g, false, 16); |
| 4436 | g->builtin_types.entry_u32 = get_int_type(g, false, 32); | 4450 | g->builtin_types.entry_u32 = get_int_type(g, false, 32); |
| 4437 | g->builtin_types.entry_u64 = get_int_type(g, false, 64); | 4451 | g->builtin_types.entry_u64 = get_int_type(g, false, 64); |
| 4452 | g->builtin_types.entry_u128 = get_int_type(g, false, 128); | ||
| 4438 | g->builtin_types.entry_i8 = get_int_type(g, true, 8); | 4453 | g->builtin_types.entry_i8 = get_int_type(g, true, 8); |
| 4439 | g->builtin_types.entry_i16 = get_int_type(g, true, 16); | 4454 | g->builtin_types.entry_i16 = get_int_type(g, true, 16); |
| 4440 | g->builtin_types.entry_i32 = get_int_type(g, true, 32); | 4455 | g->builtin_types.entry_i32 = get_int_type(g, true, 32); |
| 4441 | g->builtin_types.entry_i64 = get_int_type(g, true, 64); | 4456 | g->builtin_types.entry_i64 = get_int_type(g, true, 64); |
| 4457 | g->builtin_types.entry_i128 = get_int_type(g, true, 128); | ||
| 4442 | 4458 | ||
| 4443 | { | 4459 | { |
| 4444 | g->builtin_types.entry_c_void = get_opaque_type(g, nullptr, nullptr, "c_void"); | 4460 | g->builtin_types.entry_c_void = get_opaque_type(g, nullptr, nullptr, "c_void"); |
std/special/compiler_rt/README.md created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | This compiler-rt library is ported from [LLVM](http://compiler-rt.llvm.org/). | ||
| 2 | |||
| 3 | It's needed because LLVM emits library calls to compiler-rt when hardware lacks | ||
| 4 | functionality, for example, 64-bit integer multiplication on 32-bit x86. | ||
| 5 | |||
| 6 | This library is automatically built as-needed for the compilation target and | ||
| 7 | then statically linked and therefore is a transparent dependency for the | ||
| 8 | programmer. | ||
| 9 | |||
| 10 | Any bugs should be solved by trying to duplicate the bug upstream. | ||
| 11 | * If the bug exists upstream, get it fixed with the LLVM team and then port | ||
| 12 | the fix downstream to Zig. | ||
| 13 | * If the bug only exists in Zig, something went wrong porting the code, | ||
| 14 | and you can run the C code and Zig code side by side in a debugger | ||
| 15 | to figure out what's happening differently. | ||
std/special/compiler_rt/fixuint.zig created+50| ... | @@ -0,0 +1,50 @@ | ||
| 1 | pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuint_t { | ||
| 2 | @setDebugSafety(this, true); // TODO | ||
| 3 | |||
| 4 | const rep_t = switch (fp_t) { | ||
| 5 | f32 => u32, | ||
| 6 | f64 => u64, | ||
| 7 | f128 => u128, | ||
| 8 | else => unreachable, | ||
| 9 | }; | ||
| 10 | const srep_t = @IntType(true, rep_t.bit_count); | ||
| 11 | const significandBits = switch (fp_t) { | ||
| 12 | f32 => 23, | ||
| 13 | f64 => 52, | ||
| 14 | f128 => 112, | ||
| 15 | else => unreachable, | ||
| 16 | }; | ||
| 17 | const typeWidth = rep_t.bit_count; | ||
| 18 | const exponentBits = (typeWidth - significandBits - 1); | ||
| 19 | const signBit = (rep_t(1) << (significandBits + exponentBits)); | ||
| 20 | const maxExponent = ((1 << exponentBits) - 1); | ||
| 21 | const exponentBias = (maxExponent >> 1); | ||
| 22 | |||
| 23 | const implicitBit = (rep_t(1) << significandBits); | ||
| 24 | const significandMask = (implicitBit - 1); | ||
| 25 | |||
| 26 | // Break a into sign, exponent, significand | ||
| 27 | const aRep: rep_t = @bitCast(rep_t, a); | ||
| 28 | const absMask = signBit - 1; | ||
| 29 | const aAbs: rep_t = aRep & absMask; | ||
| 30 | |||
| 31 | const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1); | ||
| 32 | const exponent = i32(aAbs >> significandBits) - exponentBias; | ||
| 33 | const significand: rep_t = (aAbs & significandMask) | implicitBit; | ||
| 34 | |||
| 35 | // If either the value or the exponent is negative, the result is zero. | ||
| 36 | if (sign == -1 or exponent < 0) | ||
| 37 | return 0; | ||
| 38 | |||
| 39 | // If the value is too large for the integer type, saturate. | ||
| 40 | if (c_uint(exponent) >= fixuint_t.bit_count) | ||
| 41 | return ~fixuint_t(0); | ||
| 42 | |||
| 43 | // If 0 <= exponent < significandBits, right shift to get the result. | ||
| 44 | // Otherwise, shift left. | ||
| 45 | if (exponent < significandBits) { | ||
| 46 | return fixuint_t(significand >> rep_t(significandBits - exponent)); | ||
| 47 | } else { | ||
| 48 | return fixuint_t(significand) << fixuint_t(exponent - significandBits); | ||
| 49 | } | ||
| 50 | } | ||
std/special/compiler_rt/fixunsdfdi.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunsdfdi(a: f64) -> u64 { | ||
| 4 | return fixuint(f64, u64, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunsdfdi" { | ||
| 8 | _ = @import("fixunsdfdi_test.zig"); | ||
| 9 | } | ||
| 10 | |||
std/special/compiler_rt/fixunsdfdi_test.zig created+39| ... | @@ -0,0 +1,39 @@ | ||
| 1 | const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunsdfdi(a: f64, expected: u64) { | ||
| 5 | const x = __fixunsdfdi(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunsdfdi" { | ||
| 10 | test__fixunsdfdi(0.0, 0); | ||
| 11 | test__fixunsdfdi(0.5, 0); | ||
| 12 | test__fixunsdfdi(0.99, 0); | ||
| 13 | test__fixunsdfdi(1.0, 1); | ||
| 14 | test__fixunsdfdi(1.5, 1); | ||
| 15 | test__fixunsdfdi(1.99, 1); | ||
| 16 | test__fixunsdfdi(2.0, 2); | ||
| 17 | test__fixunsdfdi(2.01, 2); | ||
| 18 | test__fixunsdfdi(-0.5, 0); | ||
| 19 | test__fixunsdfdi(-0.99, 0); | ||
| 20 | test__fixunsdfdi(-1.0, 0); | ||
| 21 | test__fixunsdfdi(-1.5, 0); | ||
| 22 | test__fixunsdfdi(-1.99, 0); | ||
| 23 | test__fixunsdfdi(-2.0, 0); | ||
| 24 | test__fixunsdfdi(-2.01, 0); | ||
| 25 | |||
| 26 | test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | ||
| 27 | test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | ||
| 28 | |||
| 29 | test__fixunsdfdi(-0x1.FFFFFEp+62, 0); | ||
| 30 | test__fixunsdfdi(-0x1.FFFFFCp+62, 0); | ||
| 31 | |||
| 32 | test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | ||
| 33 | test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000); | ||
| 34 | test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | ||
| 35 | test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | ||
| 36 | |||
| 37 | test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | ||
| 38 | test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | ||
| 39 | } | ||
std/special/compiler_rt/fixunsdfsi.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunsdfsi(a: f64) -> u32 { | ||
| 4 | return fixuint(f64, u32, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunsdfsi" { | ||
| 8 | _ = @import("fixunsdfsi_test.zig"); | ||
| 9 | } | ||
| 10 | |||
std/special/compiler_rt/fixunsdfsi_test.zig created+39| ... | @@ -0,0 +1,39 @@ | ||
| 1 | const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunsdfsi(a: f64, expected: u32) { | ||
| 5 | const x = __fixunsdfsi(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunsdfsi" { | ||
| 10 | test__fixunsdfsi(0.0, 0); | ||
| 11 | |||
| 12 | test__fixunsdfsi(0.5, 0); | ||
| 13 | test__fixunsdfsi(0.99, 0); | ||
| 14 | test__fixunsdfsi(1.0, 1); | ||
| 15 | test__fixunsdfsi(1.5, 1); | ||
| 16 | test__fixunsdfsi(1.99, 1); | ||
| 17 | test__fixunsdfsi(2.0, 2); | ||
| 18 | test__fixunsdfsi(2.01, 2); | ||
| 19 | test__fixunsdfsi(-0.5, 0); | ||
| 20 | test__fixunsdfsi(-0.99, 0); | ||
| 21 | test__fixunsdfsi(-1.0, 0); | ||
| 22 | test__fixunsdfsi(-1.5, 0); | ||
| 23 | test__fixunsdfsi(-1.99, 0); | ||
| 24 | test__fixunsdfsi(-2.0, 0); | ||
| 25 | test__fixunsdfsi(-2.01, 0); | ||
| 26 | |||
| 27 | test__fixunsdfsi(0x1.000000p+31, 0x80000000); | ||
| 28 | test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF); | ||
| 29 | test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00); | ||
| 30 | test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | ||
| 31 | test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | ||
| 32 | |||
| 33 | test__fixunsdfsi(-0x1.FFFFFEp+30, 0); | ||
| 34 | test__fixunsdfsi(-0x1.FFFFFCp+30, 0); | ||
| 35 | |||
| 36 | test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF); | ||
| 37 | test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); | ||
| 38 | test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); | ||
| 39 | } | ||
std/special/compiler_rt/fixunsdfti.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunsdfti(a: f64) -> u128 { | ||
| 4 | return fixuint(f64, u128, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunsdfti" { | ||
| 8 | _ = @import("fixunsdfti_test.zig"); | ||
| 9 | } | ||
std/special/compiler_rt/fixunsdfti_test.zig created+47| ... | @@ -0,0 +1,47 @@ | ||
| 1 | const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunsdfti(a: f64, expected: u128) { | ||
| 5 | const x = __fixunsdfti(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunsdfti" { | ||
| 10 | test__fixunsdfti(0.0, 0); | ||
| 11 | |||
| 12 | test__fixunsdfti(0.5, 0); | ||
| 13 | test__fixunsdfti(0.99, 0); | ||
| 14 | test__fixunsdfti(1.0, 1); | ||
| 15 | test__fixunsdfti(1.5, 1); | ||
| 16 | test__fixunsdfti(1.99, 1); | ||
| 17 | test__fixunsdfti(2.0, 2); | ||
| 18 | test__fixunsdfti(2.01, 2); | ||
| 19 | test__fixunsdfti(-0.5, 0); | ||
| 20 | test__fixunsdfti(-0.99, 0); | ||
| 21 | test__fixunsdfti(-1.0, 0); | ||
| 22 | test__fixunsdfti(-1.5, 0); | ||
| 23 | test__fixunsdfti(-1.99, 0); | ||
| 24 | test__fixunsdfti(-2.0, 0); | ||
| 25 | test__fixunsdfti(-2.01, 0); | ||
| 26 | |||
| 27 | test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | ||
| 28 | test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | ||
| 29 | |||
| 30 | test__fixunsdfti(-0x1.FFFFFEp+62, 0); | ||
| 31 | test__fixunsdfti(-0x1.FFFFFCp+62, 0); | ||
| 32 | |||
| 33 | test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | ||
| 34 | test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000); | ||
| 35 | test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | ||
| 36 | test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | ||
| 37 | |||
| 38 | test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); | ||
| 39 | test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000); | ||
| 40 | test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | ||
| 41 | test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | ||
| 42 | test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | ||
| 43 | |||
| 44 | test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0); | ||
| 45 | test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0); | ||
| 46 | } | ||
| 47 | |||
std/special/compiler_rt/fixunssfdi.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunssfdi(a: f32) -> u64 { | ||
| 4 | return fixuint(f32, u64, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunssfdi" { | ||
| 8 | _ = @import("fixunssfdi_test.zig"); | ||
| 9 | } | ||
std/special/compiler_rt/fixunssfdi_test.zig created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunssfdi(a: f32, expected: u64) { | ||
| 5 | const x = __fixunssfdi(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunssfdi" { | ||
| 10 | test__fixunssfdi(0.0, 0); | ||
| 11 | |||
| 12 | test__fixunssfdi(0.5, 0); | ||
| 13 | test__fixunssfdi(0.99, 0); | ||
| 14 | test__fixunssfdi(1.0, 1); | ||
| 15 | test__fixunssfdi(1.5, 1); | ||
| 16 | test__fixunssfdi(1.99, 1); | ||
| 17 | test__fixunssfdi(2.0, 2); | ||
| 18 | test__fixunssfdi(2.01, 2); | ||
| 19 | test__fixunssfdi(-0.5, 0); | ||
| 20 | test__fixunssfdi(-0.99, 0); | ||
| 21 | |||
| 22 | test__fixunssfdi(-1.0, 0); | ||
| 23 | test__fixunssfdi(-1.5, 0); | ||
| 24 | test__fixunssfdi(-1.99, 0); | ||
| 25 | test__fixunssfdi(-2.0, 0); | ||
| 26 | test__fixunssfdi(-2.01, 0); | ||
| 27 | |||
| 28 | test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | ||
| 29 | test__fixunssfdi(0x1.000000p+63, 0x8000000000000000); | ||
| 30 | test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | ||
| 31 | test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | ||
| 32 | |||
| 33 | test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000); | ||
| 34 | test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000); | ||
| 35 | } | ||
std/special/compiler_rt/fixunssfsi.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunssfsi(a: f32) -> u32 { | ||
| 4 | return fixuint(f32, u32, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunssfsi" { | ||
| 8 | _ = @import("fixunssfsi_test.zig"); | ||
| 9 | } | ||
std/special/compiler_rt/fixunssfsi_test.zig created+36| ... | @@ -0,0 +1,36 @@ | ||
| 1 | const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunssfsi(a: f32, expected: u32) { | ||
| 5 | const x = __fixunssfsi(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunssfsi" { | ||
| 10 | test__fixunssfsi(0.0, 0); | ||
| 11 | |||
| 12 | test__fixunssfsi(0.5, 0); | ||
| 13 | test__fixunssfsi(0.99, 0); | ||
| 14 | test__fixunssfsi(1.0, 1); | ||
| 15 | test__fixunssfsi(1.5, 1); | ||
| 16 | test__fixunssfsi(1.99, 1); | ||
| 17 | test__fixunssfsi(2.0, 2); | ||
| 18 | test__fixunssfsi(2.01, 2); | ||
| 19 | test__fixunssfsi(-0.5, 0); | ||
| 20 | test__fixunssfsi(-0.99, 0); | ||
| 21 | |||
| 22 | test__fixunssfsi(-1.0, 0); | ||
| 23 | test__fixunssfsi(-1.5, 0); | ||
| 24 | test__fixunssfsi(-1.99, 0); | ||
| 25 | test__fixunssfsi(-2.0, 0); | ||
| 26 | test__fixunssfsi(-2.01, 0); | ||
| 27 | |||
| 28 | test__fixunssfsi(0x1.000000p+31, 0x80000000); | ||
| 29 | test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF); | ||
| 30 | test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00); | ||
| 31 | test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | ||
| 32 | test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | ||
| 33 | |||
| 34 | test__fixunssfsi(-0x1.FFFFFEp+30, 0); | ||
| 35 | test__fixunssfsi(-0x1.FFFFFCp+30, 0); | ||
| 36 | } | ||
std/special/compiler_rt/fixunssfti.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunssfti(a: f32) -> u128 { | ||
| 4 | return fixuint(f32, u128, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunssfti" { | ||
| 8 | _ = @import("fixunssfti_test.zig"); | ||
| 9 | } | ||
| 10 | |||
std/special/compiler_rt/fixunssfti_test.zig created+41| ... | @@ -0,0 +1,41 @@ | ||
| 1 | const __fixunssfti = @import("fixunssfti.zig").__fixunssfti; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunssfti(a: f32, expected: u128) { | ||
| 5 | const x = __fixunssfti(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunssfti" { | ||
| 10 | test__fixunssfti(0.0, 0); | ||
| 11 | |||
| 12 | test__fixunssfti(0.5, 0); | ||
| 13 | test__fixunssfti(0.99, 0); | ||
| 14 | test__fixunssfti(1.0, 1); | ||
| 15 | test__fixunssfti(1.5, 1); | ||
| 16 | test__fixunssfti(1.99, 1); | ||
| 17 | test__fixunssfti(2.0, 2); | ||
| 18 | test__fixunssfti(2.01, 2); | ||
| 19 | test__fixunssfti(-0.5, 0); | ||
| 20 | test__fixunssfti(-0.99, 0); | ||
| 21 | |||
| 22 | test__fixunssfti(-1.0, 0); | ||
| 23 | test__fixunssfti(-1.5, 0); | ||
| 24 | test__fixunssfti(-1.99, 0); | ||
| 25 | test__fixunssfti(-2.0, 0); | ||
| 26 | test__fixunssfti(-2.01, 0); | ||
| 27 | |||
| 28 | test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | ||
| 29 | test__fixunssfti(0x1.000000p+63, 0x8000000000000000); | ||
| 30 | test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | ||
| 31 | test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | ||
| 32 | test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); | ||
| 33 | test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000); | ||
| 34 | test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); | ||
| 35 | test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); | ||
| 36 | |||
| 37 | test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000); | ||
| 38 | test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000); | ||
| 39 | test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000); | ||
| 40 | test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000); | ||
| 41 | } | ||
std/special/compiler_rt/fixunstfdi.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunstfdi(a: f128) -> u64 { | ||
| 4 | return fixuint(f128, u64, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "import fixunstfdi" { | ||
| 8 | _ = @import("fixunstfdi_test.zig"); | ||
| 9 | } | ||
std/special/compiler_rt/fixunstfdi_test.zig created+49| ... | @@ -0,0 +1,49 @@ | ||
| 1 | const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi; | ||
| 2 | const assert = @import("../../debug.zig").assert; | ||
| 3 | |||
| 4 | fn test__fixunstfdi(a: f128, expected: u64) { | ||
| 5 | const x = __fixunstfdi(a); | ||
| 6 | assert(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "fixunstfdi" { | ||
| 10 | test__fixunstfdi(0.0, 0); | ||
| 11 | |||
| 12 | test__fixunstfdi(0.5, 0); | ||
| 13 | test__fixunstfdi(0.99, 0); | ||
| 14 | test__fixunstfdi(1.0, 1); | ||
| 15 | test__fixunstfdi(1.5, 1); | ||
| 16 | test__fixunstfdi(1.99, 1); | ||
| 17 | test__fixunstfdi(2.0, 2); | ||
| 18 | test__fixunstfdi(2.01, 2); | ||
| 19 | test__fixunstfdi(-0.5, 0); | ||
| 20 | test__fixunstfdi(-0.99, 0); | ||
| 21 | test__fixunstfdi(-1.0, 0); | ||
| 22 | test__fixunstfdi(-1.5, 0); | ||
| 23 | test__fixunstfdi(-1.99, 0); | ||
| 24 | test__fixunstfdi(-2.0, 0); | ||
| 25 | test__fixunstfdi(-2.01, 0); | ||
| 26 | |||
| 27 | test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | ||
| 28 | test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | ||
| 29 | |||
| 30 | test__fixunstfdi(-0x1.FFFFFEp+62, 0); | ||
| 31 | test__fixunstfdi(-0x1.FFFFFCp+62, 0); | ||
| 32 | |||
| 33 | test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | ||
| 34 | test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | ||
| 35 | |||
| 36 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | ||
| 37 | test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | ||
| 38 | |||
| 39 | test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); | ||
| 40 | test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001); | ||
| 41 | test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000); | ||
| 42 | test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); | ||
| 43 | test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); | ||
| 44 | test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF); | ||
| 45 | |||
| 46 | test__fixunstfdi(-0x1.0000000000000000p+63, 0); | ||
| 47 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0); | ||
| 48 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0); | ||
| 49 | } | ||
std/special/compiler_rt/fixunstfsi.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunstfsi(a: f128) -> u32 { | ||
| 4 | return fixuint(f128, u32, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "fixunstfsi" { | ||
| 8 | _ = @import("fixunstfsi_test.zig"); | ||
| 9 | } | ||
std/special/compiler_rt/fixunstfti.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | const fixuint = @import("fixuint.zig").fixuint; | ||
| 2 | |||
| 3 | export fn __fixunstfti(a: f128) -> u128 { | ||
| 4 | return fixuint(f128, u128, a); | ||
| 5 | } | ||
| 6 | |||
| 7 | test "fixunstfti" { | ||
| 8 | _ = @import("fixunstfti_test.zig"); | ||
| 9 | } | ||
| 10 | |||
std/special/compiler_rt/index.zig+19-4| ... | @@ -1,6 +1,20 @@ | ... | @@ -1,6 +1,20 @@ |
| 1 | // Find all the exported functions. | ||
| 2 | comptime { | ||
| 3 | _ = @import("fixunsdfdi.zig"); | ||
| 4 | _ = @import("fixunsdfsi.zig"); | ||
| 5 | _ = @import("fixunsdfti.zig"); | ||
| 6 | _ = @import("fixunssfdi.zig"); | ||
| 7 | _ = @import("fixunssfsi.zig"); | ||
| 8 | _ = @import("fixunssfti.zig"); | ||
| 9 | _ = @import("fixunstfdi.zig"); | ||
| 10 | _ = @import("fixunstfsi.zig"); | ||
| 11 | _ = @import("fixunstfti.zig"); | ||
| 12 | _ = @import("udivti3.zig"); | ||
| 13 | _ = @import("umodti3.zig"); | ||
| 14 | } | ||
| 15 | |||
| 1 | const builtin = @import("builtin"); | 16 | const builtin = @import("builtin"); |
| 2 | 17 | ||
| 3 | const CHAR_BIT = 8; | ||
| 4 | const du_int = u64; | 18 | const du_int = u64; |
| 5 | const di_int = i64; | 19 | const di_int = i64; |
| 6 | const si_int = c_int; | 20 | const si_int = c_int; |
| ... | @@ -23,8 +37,8 @@ fn du_int_to_udwords(x: du_int) -> udwords { | ... | @@ -23,8 +37,8 @@ fn du_int_to_udwords(x: du_int) -> udwords { |
| 23 | export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { | 37 | export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int { |
| 24 | @setDebugSafety(this, false); | 38 | @setDebugSafety(this, false); |
| 25 | 39 | ||
| 26 | const n_uword_bits = @sizeOf(su_int) * CHAR_BIT; | 40 | const n_uword_bits = su_int.bit_count; |
| 27 | const n_udword_bits = @sizeOf(du_int) * CHAR_BIT; | 41 | const n_udword_bits = du_int.bit_count; |
| 28 | var n = du_int_to_udwords(a); | 42 | var n = du_int_to_udwords(a); |
| 29 | var d = du_int_to_udwords(b); | 43 | var d = du_int_to_udwords(b); |
| 30 | var q: udwords = undefined; | 44 | var q: udwords = undefined; |
| ... | @@ -219,6 +233,7 @@ fn isArmArch() -> bool { | ... | @@ -219,6 +233,7 @@ fn isArmArch() -> bool { |
| 219 | builtin.Arch.armv8_2a, | 233 | builtin.Arch.armv8_2a, |
| 220 | builtin.Arch.armv8_1a, | 234 | builtin.Arch.armv8_1a, |
| 221 | builtin.Arch.armv8, | 235 | builtin.Arch.armv8, |
| 236 | builtin.Arch.armv8r, | ||
| 222 | builtin.Arch.armv8m_baseline, | 237 | builtin.Arch.armv8m_baseline, |
| 223 | builtin.Arch.armv8m_mainline, | 238 | builtin.Arch.armv8m_mainline, |
| 224 | builtin.Arch.armv7, | 239 | builtin.Arch.armv7, |
| ... | @@ -278,7 +293,7 @@ export fn __aeabi_uidiv(n: su_int, d: su_int) -> su_int { | ... | @@ -278,7 +293,7 @@ export fn __aeabi_uidiv(n: su_int, d: su_int) -> su_int { |
| 278 | export fn __udivsi3(n: su_int, d: su_int) -> su_int { | 293 | export fn __udivsi3(n: su_int, d: su_int) -> su_int { |
| 279 | @setDebugSafety(this, false); | 294 | @setDebugSafety(this, false); |
| 280 | 295 | ||
| 281 | const n_uword_bits: c_uint = @sizeOf(su_int) * CHAR_BIT; | 296 | const n_uword_bits: c_uint = su_int.bit_count; |
| 282 | // special cases | 297 | // special cases |
| 283 | if (d == 0) | 298 | if (d == 0) |
| 284 | return 0; // ?! | 299 | return 0; // ?! |
std/special/compiler_rt/udivti3.zig createdstd/special/compiler_rt/umodti3.zig createdtest/cases/math.zig+26| ... | @@ -284,3 +284,29 @@ fn testShrExact(x: u8) { | ... | @@ -284,3 +284,29 @@ fn testShrExact(x: u8) { |
| 284 | const shifted = @shrExact(x, 2); | 284 | const shifted = @shrExact(x, 2); |
| 285 | assert(shifted == 0b00101101); | 285 | assert(shifted == 0b00101101); |
| 286 | } | 286 | } |
| 287 | |||
| 288 | test "big number addition" { | ||
| 289 | comptime { | ||
| 290 | assert( | ||
| 291 | 35361831660712422535336160538497375248 + | ||
| 292 | 101752735581729509668353361206450473702 == | ||
| 293 | 137114567242441932203689521744947848950); | ||
| 294 | assert( | ||
| 295 | 594491908217841670578297176641415611445982232488944558774612 + | ||
| 296 | 390603545391089362063884922208143568023166603618446395589768 == | ||
| 297 | 985095453608931032642182098849559179469148836107390954364380); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | test "big number multiplication" { | ||
| 302 | comptime { | ||
| 303 | assert( | ||
| 304 | 45960427431263824329884196484953148229 * | ||
| 305 | 128339149605334697009938835852565949723 == | ||
| 306 | 5898522172026096622534201617172456926982464453350084962781392314016180490567); | ||
| 307 | assert( | ||
| 308 | 594491908217841670578297176641415611445982232488944558774612 * | ||
| 309 | 390603545391089362063884922208143568023166603618446395589768 == | ||
| 310 | 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016); | ||
| 311 | } | ||
| 312 | } |